forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			94 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import Combine from "../Base/Combine"
 | 
						|
import { Store, UIEventSource } from "../../Logic/UIEventSource"
 | 
						|
import UserRelatedState from "../../Logic/State/UserRelatedState"
 | 
						|
import Translations from "../i18n/Translations"
 | 
						|
import { Utils } from "../../Utils"
 | 
						|
import { FlowStep } from "./FlowStep"
 | 
						|
import Title from "../Base/Title"
 | 
						|
import BaseUIElement from "../BaseUIElement"
 | 
						|
import Histogram from "../BigComponents/Histogram"
 | 
						|
import Toggleable from "../Base/Toggleable"
 | 
						|
import List from "../Base/List"
 | 
						|
import CheckBoxes from "../Input/Checkboxes"
 | 
						|
import { Feature, Point } from "geojson"
 | 
						|
 | 
						|
/**
 | 
						|
 * Shows the attributes by value, requests to check them of
 | 
						|
 */
 | 
						|
export class PreviewAttributesPanel
 | 
						|
    extends Combine
 | 
						|
    implements FlowStep<{ features: Feature<Point>[] }>
 | 
						|
{
 | 
						|
    public readonly IsValid: Store<boolean>
 | 
						|
    public readonly Value: Store<{ features: Feature<Point>[] }>
 | 
						|
 | 
						|
    constructor(state: UserRelatedState, geojson: { features: Feature<Point>[] }) {
 | 
						|
        const t = Translations.t.importHelper.previewAttributes
 | 
						|
 | 
						|
        const propertyKeys = new Set<string>()
 | 
						|
        for (const f of geojson.features) {
 | 
						|
            Object.keys(f.properties).forEach((key) => propertyKeys.add(key))
 | 
						|
        }
 | 
						|
 | 
						|
        const attributeOverview: BaseUIElement[] = []
 | 
						|
 | 
						|
        const n = geojson.features.length
 | 
						|
        for (const key of Array.from(propertyKeys)) {
 | 
						|
            const values = Utils.NoNull(geojson.features.map((f) => f.properties[key]))
 | 
						|
            const allSame = !values.some((v) => v !== values[0])
 | 
						|
            let countSummary: BaseUIElement
 | 
						|
            if (values.length === n) {
 | 
						|
                countSummary = t.allAttributesSame
 | 
						|
            } else {
 | 
						|
                countSummary = t.someHaveSame.Subs({
 | 
						|
                    count: values.length,
 | 
						|
                    percentage: Math.floor((100 * values.length) / n),
 | 
						|
                })
 | 
						|
            }
 | 
						|
            if (allSame) {
 | 
						|
                attributeOverview.push(new Title(key + "=" + values[0]))
 | 
						|
                attributeOverview.push(countSummary)
 | 
						|
                continue
 | 
						|
            }
 | 
						|
 | 
						|
            const uniqueCount = new Set(values).size
 | 
						|
            if (uniqueCount !== values.length && uniqueCount < 15) {
 | 
						|
                attributeOverview.push()
 | 
						|
                // There are some overlapping values: histogram time!
 | 
						|
                let hist: BaseUIElement = new Combine([
 | 
						|
                    countSummary,
 | 
						|
                    new Histogram(new UIEventSource<string[]>(values), "Value", "Occurence", {
 | 
						|
                        sortMode: "count-rev",
 | 
						|
                    }),
 | 
						|
                ]).SetClass("flex flex-col")
 | 
						|
 | 
						|
                const title = new Title(key + "=*")
 | 
						|
                if (uniqueCount > 15) {
 | 
						|
                    hist = new Toggleable(title, hist.SetClass("block")).Collapse()
 | 
						|
                } else {
 | 
						|
                    attributeOverview.push(title)
 | 
						|
                }
 | 
						|
 | 
						|
                attributeOverview.push(hist)
 | 
						|
                continue
 | 
						|
            }
 | 
						|
 | 
						|
            // All values are different or too much unique values, we add a boring (but collapsable) list
 | 
						|
            attributeOverview.push(
 | 
						|
                new Toggleable(new Title(key + "=*"), new Combine([countSummary, new List(values)]))
 | 
						|
            )
 | 
						|
        }
 | 
						|
 | 
						|
        const confirm = new CheckBoxes([t.inspectLooksCorrect])
 | 
						|
 | 
						|
        super([
 | 
						|
            new Title(t.inspectDataTitle.Subs({ count: geojson.features.length })),
 | 
						|
            "Extra remark: An attribute with 'source' or 'src' will be added as 'source' into the map pin; an attribute 'note' will be added into the map pin as well. These values won't be imported",
 | 
						|
            ...attributeOverview,
 | 
						|
            confirm,
 | 
						|
        ])
 | 
						|
 | 
						|
        this.Value = new UIEventSource<{ features: Feature<Point>[] }>(geojson)
 | 
						|
        this.IsValid = confirm.GetValue().map((selected) => selected.length == 1)
 | 
						|
    }
 | 
						|
}
 |