forked from MapComplete/MapComplete
		
	
		
			
	
	
		
			74 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			74 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| 
								 | 
							
								import {VariableUiElement} from "../Base/VariableUIElement";
							 | 
						||
| 
								 | 
							
								import {UIEventSource} from "../../Logic/UIEventSource";
							 | 
						||
| 
								 | 
							
								import Table from "../Base/Table";
							 | 
						||
| 
								 | 
							
								import Combine from "../Base/Combine";
							 | 
						||
| 
								 | 
							
								import {FixedUiElement} from "../Base/FixedUiElement";
							 | 
						||
| 
								 | 
							
								import {Utils} from "../../Utils";
							 | 
						||
| 
								 | 
							
								import BaseUIElement from "../BaseUIElement";
							 | 
						||
| 
								 | 
							
								import Translations from "../i18n/Translations";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default class Histogram<T> extends VariableUiElement {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    private static defaultPalette = [
							 | 
						||
| 
								 | 
							
								        "#ff5858",
							 | 
						||
| 
								 | 
							
								        "#ffad48",
							 | 
						||
| 
								 | 
							
								        "#ffff59",
							 | 
						||
| 
								 | 
							
								        "#9d62d9",
							 | 
						||
| 
								 | 
							
								        "#56bd56",
							 | 
						||
| 
								 | 
							
								        "#63a9ff",
							 | 
						||
| 
								 | 
							
								        "#fa61fa"
							 | 
						||
| 
								 | 
							
								    ]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    constructor(values: UIEventSource<string[]>,
							 | 
						||
| 
								 | 
							
								                title: string | BaseUIElement,
							 | 
						||
| 
								 | 
							
								                countTitle: string | BaseUIElement,
							 | 
						||
| 
								 | 
							
								                assignColor?: (t0: string) => string
							 | 
						||
| 
								 | 
							
								    ) {
							 | 
						||
| 
								 | 
							
								        super(values.map(values => {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (values === undefined) {
							 | 
						||
| 
								 | 
							
								                return undefined;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            values = Utils.NoNull(values)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            const counts = new Map<string, number>()
							 | 
						||
| 
								 | 
							
								            for (const value of values) {
							 | 
						||
| 
								 | 
							
								                const c = counts.get(value) ?? 0;
							 | 
						||
| 
								 | 
							
								                counts.set(value, c + 1);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            const keys = Array.from(counts.keys());
							 | 
						||
| 
								 | 
							
								            keys.sort()
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            const max = Math.max(...Array.from(counts.values()))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            const fallbackColor = (keyValue: string) => {
							 | 
						||
| 
								 | 
							
								                const index = keys.indexOf(keyValue)
							 | 
						||
| 
								 | 
							
								                return Histogram.defaultPalette[index % Histogram.defaultPalette.length]
							 | 
						||
| 
								 | 
							
								            };
							 | 
						||
| 
								 | 
							
								            let actualAssignColor = undefined;
							 | 
						||
| 
								 | 
							
								            if (assignColor === undefined) {
							 | 
						||
| 
								 | 
							
								                actualAssignColor = fallbackColor;
							 | 
						||
| 
								 | 
							
								            }else{
							 | 
						||
| 
								 | 
							
								                actualAssignColor = (keyValue: string) => {
							 | 
						||
| 
								 | 
							
								                    return assignColor(keyValue) ?? fallbackColor(keyValue)
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return new Table(
							 | 
						||
| 
								 | 
							
								                [Translations.W(title), countTitle],
							 | 
						||
| 
								 | 
							
								                keys.map(key => [
							 | 
						||
| 
								 | 
							
								                    key,
							 | 
						||
| 
								 | 
							
								                    new Combine([
							 | 
						||
| 
								 | 
							
								                    new Combine([new FixedUiElement("" + counts.get(key)).SetClass("font-bold rounded-full block")])
							 | 
						||
| 
								 | 
							
								                            .SetClass("flex justify-center rounded border border-black")
							 | 
						||
| 
								 | 
							
								                            .SetStyle(`background: ${actualAssignColor(key)}; width: ${100 * counts.get(key) / max}%`)
							 | 
						||
| 
								 | 
							
								                    ]).SetClass("block w-full")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                ]),
							 | 
						||
| 
								 | 
							
								                keys.map(_ => ["width: 20%"])
							 | 
						||
| 
								 | 
							
								            ).SetClass("w-full");
							 | 
						||
| 
								 | 
							
								        }));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |