Refactoring: port statistics view

This commit is contained in:
Pieter Vander Vennet 2023-04-24 03:22:43 +02:00
parent 78c56f6fa2
commit fcc49766d4
8 changed files with 103 additions and 169 deletions

View file

@ -10,14 +10,14 @@ import type { Writable } from "svelte/store";
import If from "../Base/If.svelte";
import Dropdown from "../Base/Dropdown.svelte";
import { onDestroy } from "svelte";
import { UIEventSource } from "../../Logic/UIEventSource";
import { ImmutableStore, Store } from "../../Logic/UIEventSource";
import FilterviewWithFields from "./FilterviewWithFields.svelte";
import Tr from "../Base/Tr.svelte";
import Translations from "../i18n/Translations";
export let filteredLayer: FilteredLayer;
export let highlightedLayer: UIEventSource<string> | undefined;
export let zoomlevel: UIEventSource<number>;
export let highlightedLayer: Store<string | undefined> = new ImmutableStore(undefined);
export let zoomlevel: Store<number> = new ImmutableStore(22);
let layer: LayerConfig = filteredLayer.layerDef;
let isDisplayed: boolean = filteredLayer.isDisplayed.data;
onDestroy(filteredLayer.isDisplayed.addCallbackAndRunD(d => {

View file

@ -17,7 +17,7 @@
let fieldValues: Record<string, UIEventSource<string>> = {};
let fieldTypes: Record<string, string> = {};
let appliedFilter = <UIEventSource<string>>filteredLayer.appliedFilters.get(id);
let initialState: Record<string, string> = JSON.parse(appliedFilter.data ?? "{}");
let initialState: Record<string, string> = JSON.parse(appliedFilter?.data ?? "{}");
function setFields() {
const properties: Record<string, string> = {};
@ -30,7 +30,7 @@
properties[k] = v;
}
}
appliedFilter.setData(FilteredLayer.fieldsToString(properties));
appliedFilter?.setData(FilteredLayer.fieldsToString(properties));
}
for (const field of option.fields) {
@ -38,7 +38,7 @@
fieldTypes[field.name + "}"] = field.type;
const src = new UIEventSource<string>(initialState[field.name] ?? "");
fieldValues[field.name + "}"] = src;
onDestroy(src.addCallback(() => {
onDestroy(src.stabilized(200).addCallback(() => {
setFields();
}));
}

View file

@ -25,7 +25,13 @@ export class StackedRenderingChart extends ChartJs {
groupToOtherCutoff: options?.groupToOtherCutoff,
})
if (labels === undefined || data === undefined) {
console.error("Could not extract data and labels for ", tr, " with features", features)
console.error(
"Could not extract data and labels for ",
tr,
" with features",
features,
": no labels or no data"
)
throw "No labels or data given..."
}
// labels: ["cyclofix", "buurtnatuur", ...]; data : [ ["cyclofix-changeset", "cyclofix-changeset", ...], ["buurtnatuur-cs", "buurtnatuur-cs"], ... ]

View file

@ -7,24 +7,25 @@ import Loading from "./Base/Loading"
import { Utils } from "../Utils"
import Combine from "./Base/Combine"
import { StackedRenderingChart } from "./BigComponents/TagRenderingChart"
import { LayerFilterPanel } from "./BigComponents/FilterView"
import MapState from "../Logic/State/MapState"
import BaseUIElement from "./BaseUIElement"
import Title from "./Base/Title"
import { FixedUiElement } from "./Base/FixedUiElement"
import List from "./Base/List"
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"
import mcChanges from "../assets/generated/themes/mapcomplete-changes.json"
import SvelteUIElement from "./Base/SvelteUIElement"
import Filterview from "./BigComponents/Filterview.svelte"
import FilteredLayer from "../Models/FilteredLayer"
class StatisticsForOverviewFile extends Combine {
constructor(homeUrl: string, paths: string[]) {
paths = paths.filter((p) => !p.endsWith("file-overview.json"))
const layer = new LayoutConfig(<any>mcChanges, true).layers[0]
const filteredLayer = MapState.InitializeFilteredLayers(
{ id: "statistics-view", layers: [layer] },
undefined
)[0]
const filterPanel = new LayerFilterPanel(undefined, filteredLayer)
const appliedFilters = filteredLayer.appliedFilters
const filteredLayer = new FilteredLayer(layer)
const filterPanel = new Combine([
new Title("Filters"),
new SvelteUIElement(Filterview, { filteredLayer }),
])
const downloaded = new UIEventSource<{ features: ChangeSetData[] }[]>([])
@ -63,20 +64,10 @@ class StatisticsForOverviewFile extends Combine {
return loading
}
let overview = ChangesetsOverview.fromDirtyData(
const overview = ChangesetsOverview.fromDirtyData(
[].concat(...downloaded.map((d) => d.features))
)
if (appliedFilters.data.size > 0) {
appliedFilters.data.forEach((filterSpec) => {
const tf = filterSpec?.currentFilter
if (tf === undefined) {
return
}
overview = overview.filter((cs) =>
tf.matchesProperties(cs.properties)
)
})
}
).filter((cs) => filteredLayer.isShown(<any>cs.properties))
console.log("Overview is", overview)
if (overview._meta.length === 0) {
return "No data matched the filter"
@ -143,6 +134,10 @@ class StatisticsForOverviewFile extends Combine {
new Title("Breakdown"),
]
for (const tr of trs) {
if (tr.question === undefined) {
continue
}
console.log(tr)
let total = undefined
if (tr.freeform?.key !== undefined) {
total = new Set(
@ -174,7 +169,7 @@ class StatisticsForOverviewFile extends Combine {
return new Combine(elements)
},
[appliedFilters]
[filteredLayer.currentFilter]
)
).SetClass("block w-full h-full"),
])
@ -232,30 +227,12 @@ class ChangesetsOverview {
}
public readonly _meta: ChangeSetData[]
public static fromDirtyData(meta: ChangeSetData[]) {
return new ChangesetsOverview(meta?.map((cs) => ChangesetsOverview.cleanChangesetData(cs)))
}
private constructor(meta: ChangeSetData[]) {
this._meta = Utils.NoNull(meta)
}
public filter(predicate: (cs: ChangeSetData) => boolean) {
return new ChangesetsOverview(this._meta.filter(predicate))
}
public sum(key: string, excludeThemes: Set<string>): number {
let s = 0
for (const feature of this._meta) {
if (excludeThemes.has(feature.properties.theme)) {
continue
}
const parsed = Number(feature.properties[key])
if (!isNaN(parsed)) {
s += parsed
}
}
return s
public static fromDirtyData(meta: ChangeSetData[]) {
return new ChangesetsOverview(meta?.map((cs) => ChangesetsOverview.cleanChangesetData(cs)))
}
private static cleanChangesetData(cs: ChangeSetData): ChangeSetData {
@ -286,6 +263,24 @@ class ChangesetsOverview {
} catch (e) {}
return cs
}
public filter(predicate: (cs: ChangeSetData) => boolean) {
return new ChangesetsOverview(this._meta.filter(predicate))
}
public sum(key: string, excludeThemes: Set<string>): number {
let s = 0
for (const feature of this._meta) {
if (excludeThemes.has(feature.properties.theme)) {
continue
}
const parsed = Number(feature.properties[key])
if (!isNaN(parsed)) {
s += parsed
}
}
return s
}
}
interface ChangeSetData {
@ -323,3 +318,5 @@ interface ChangeSetData {
language: string
}
}
new StatisticsGUI().AttachTo("main")