forked from MapComplete/MapComplete
Add a histogram visualisation
This commit is contained in:
parent
962e364bad
commit
d4909734a1
2 changed files with 77 additions and 65 deletions
|
@ -17,19 +17,33 @@ export default class Table extends BaseUIElement {
|
|||
this._contents = contents.map(row => row.map(Translations.W));
|
||||
}
|
||||
|
||||
AsMarkdown(): string {
|
||||
|
||||
const headerMarkdownParts = this._header.map(hel => hel?.AsMarkdown() ?? " ")
|
||||
const header = headerMarkdownParts.join(" | ");
|
||||
const headerSep = headerMarkdownParts.map(part => '-'.repeat(part.length + 2)).join("|")
|
||||
const table = this._contents.map(row => row.map(el => el.AsMarkdown() ?? " ").join("|")).join("\n")
|
||||
|
||||
return [header, headerSep, table, ""].join("\n")
|
||||
}
|
||||
|
||||
protected InnerConstructElement(): HTMLElement {
|
||||
const table = document.createElement("table")
|
||||
|
||||
const headerElems = Utils.NoNull((this._header ?? []).map(elems => elems.ConstructElement()))
|
||||
if (headerElems.length > 0) {
|
||||
|
||||
const thead = document.createElement("thead")
|
||||
|
||||
const tr = document.createElement("tr");
|
||||
headerElems.forEach(headerElem => {
|
||||
const td = document.createElement("th")
|
||||
td.appendChild(headerElem)
|
||||
tr.appendChild(td)
|
||||
})
|
||||
table.appendChild(tr)
|
||||
thead.appendChild(tr)
|
||||
table.appendChild(thead)
|
||||
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._contents.length; i++) {
|
||||
|
@ -58,14 +72,4 @@ export default class Table extends BaseUIElement {
|
|||
return table;
|
||||
}
|
||||
|
||||
AsMarkdown(): string {
|
||||
|
||||
const headerMarkdownParts = this._header.map(hel => hel?.AsMarkdown() ?? " ")
|
||||
const header =headerMarkdownParts.join(" | ");
|
||||
const headerSep = headerMarkdownParts.map(part => '-'.repeat(part.length + 2)).join("|")
|
||||
const table = this._contents.map(row => row.map(el => el.AsMarkdown()?? " ").join("|")).join("\n")
|
||||
|
||||
return [header, headerSep, table, ""].join("\n")
|
||||
}
|
||||
|
||||
}
|
|
@ -18,9 +18,9 @@ import State from "../State";
|
|||
import {ImageSearcher} from "../Logic/Actors/ImageSearcher";
|
||||
import BaseUIElement from "./BaseUIElement";
|
||||
import LayerConfig from "../Customizations/JSON/LayerConfig";
|
||||
import List from "./Base/List";
|
||||
import Title from "./Base/Title";
|
||||
import Table from "./Base/Table";
|
||||
import Histogram from "./BigComponents/Histogram";
|
||||
|
||||
export default class SpecialVisualizations {
|
||||
|
||||
|
@ -156,51 +156,59 @@ export default class SpecialVisualizations {
|
|||
{
|
||||
name: "key",
|
||||
doc: "The key to be read and to generate a histogram from"
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
doc: "The text to put above the given values column",
|
||||
defaultValue: ""
|
||||
},
|
||||
{
|
||||
name: "countHeader",
|
||||
doc: "The text to put above the counts",
|
||||
defaultValue: ""
|
||||
},
|
||||
{
|
||||
name: "colors",
|
||||
doc: "(Matches all resting arguments - optional) Matches a regex onto a color value, e.g. `3[a-zA-Z+-]*:#33cc33`"
|
||||
|
||||
}
|
||||
],
|
||||
constr: (state: State, tagSource: UIEventSource<any>, args: string[]) => {
|
||||
return new VariableUiElement(
|
||||
tagSource
|
||||
.map(tags => tags[args[0]])
|
||||
.map(listStr => {
|
||||
try{
|
||||
if("" === listStr ?? ""){
|
||||
return "Nothing defined";
|
||||
}
|
||||
const list : string[] = JSON.parse(listStr)
|
||||
|
||||
if(list.length === 0){
|
||||
return "No values given";
|
||||
}
|
||||
|
||||
const counts = new Map<string, number>()
|
||||
for (const key of list) {
|
||||
if(key === null || key === undefined || key === ""){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!counts.has(key)){
|
||||
counts.set(key, 1)
|
||||
}else{
|
||||
counts.set(key, counts.get(key) + 1)
|
||||
}
|
||||
}
|
||||
const keys = Array.from(counts.keys())
|
||||
keys.sort()
|
||||
|
||||
return new List(keys.map(key=> new Combine[
|
||||
new FixedUiElement(key).SetClass("font-bold"),
|
||||
counts.get(key)
|
||||
]));
|
||||
|
||||
|
||||
}catch{
|
||||
return "Could not generate histogram" // TODO translate
|
||||
}
|
||||
|
||||
|
||||
let assignColors = undefined;
|
||||
if (args.length >= 3) {
|
||||
const colors = [...args]
|
||||
colors.splice(0, 3)
|
||||
const mapping = colors.map(c => {
|
||||
const splitted = c.split(":");
|
||||
const value = splitted.pop()
|
||||
const regex = splitted.join(":")
|
||||
return {regex: "^" + regex + "$", color: value}
|
||||
})
|
||||
)
|
||||
assignColors = (key) => {
|
||||
for (const kv of mapping) {
|
||||
if (key.match(kv.regex) !== null) {
|
||||
return kv.color
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
const listSource: UIEventSource<string[]> = tagSource
|
||||
.map(tags => {
|
||||
try {
|
||||
const value = tags[args[0]]
|
||||
if (value === "" || value === undefined) {
|
||||
return undefined
|
||||
}
|
||||
return JSON.parse(value)
|
||||
} catch (e) {
|
||||
console.error("Could not load histogram: parsing of the list failed: ", e)
|
||||
return undefined;
|
||||
}
|
||||
})
|
||||
return new Histogram(listSource, args[1], args[2], assignColors)
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue