diff --git a/.gitignore b/.gitignore index e851713..cdc63ba 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,6 @@ assets/generated/* /*.webmanifest /*.html !/index.html -.parcel-cache \ No newline at end of file +.parcel-cache +Docs/Tools/stats.*.json +Docs/Tools/stats.csv diff --git a/Customizations/JSON/TagRenderingConfig.ts b/Customizations/JSON/TagRenderingConfig.ts index 675893c..a8169a6 100644 --- a/Customizations/JSON/TagRenderingConfig.ts +++ b/Customizations/JSON/TagRenderingConfig.ts @@ -74,7 +74,7 @@ export default class TagRenderingConfig { } if(this.freeform.addExtraTags){ const usedKeys = new And(this.freeform.addExtraTags).usedKeys(); - if(usedKeys.indexOf(this.freeform.key)){ + if(usedKeys.indexOf(this.freeform.key) >= 0){ throw `The freeform key ${this.freeform.key} will be overwritten by one of the extra tags, as they use the same key too. This is in ${context}`; } } diff --git a/Docs/Tools/Contributors in 2020.png b/Docs/Tools/Contributors in 2020.png index 981c074..519adee 100644 Binary files a/Docs/Tools/Contributors in 2020.png and b/Docs/Tools/Contributors in 2020.png differ diff --git a/Docs/Tools/Contributors in 2021.png b/Docs/Tools/Contributors in 2021.png index 36e9003..ae12d21 100644 Binary files a/Docs/Tools/Contributors in 2021.png and b/Docs/Tools/Contributors in 2021.png differ diff --git a/Docs/Tools/Contributors.png b/Docs/Tools/Contributors.png index c72f64b..19008e3 100644 Binary files a/Docs/Tools/Contributors.png and b/Docs/Tools/Contributors.png differ diff --git a/Docs/Tools/CumulativeContributors in 2021.png b/Docs/Tools/CumulativeContributors in 2021.png index cbf6c6e..856e022 100644 Binary files a/Docs/Tools/CumulativeContributors in 2021.png and b/Docs/Tools/CumulativeContributors in 2021.png differ diff --git a/Docs/Tools/CumulativeContributors.png b/Docs/Tools/CumulativeContributors.png index 5415351..ee495c5 100644 Binary files a/Docs/Tools/CumulativeContributors.png and b/Docs/Tools/CumulativeContributors.png differ diff --git a/Docs/Tools/Theme distribution in 2021.png b/Docs/Tools/Theme distribution in 2021.png index 51a052e..3723992 100644 Binary files a/Docs/Tools/Theme distribution in 2021.png and b/Docs/Tools/Theme distribution in 2021.png differ diff --git a/Docs/Tools/Theme distribution.png b/Docs/Tools/Theme distribution.png index 00e00af..9d68193 100644 Binary files a/Docs/Tools/Theme distribution.png and b/Docs/Tools/Theme distribution.png differ diff --git a/Docs/Tools/csvGrapher.py b/Docs/Tools/csvGrapher.py index 46a2510..6d9e195 100644 --- a/Docs/Tools/csvGrapher.py +++ b/Docs/Tools/csvGrapher.py @@ -111,14 +111,15 @@ def pyplot_init(): def create_usercount_graphs(stats, year="", show=False): + print("Creating usercount graphs "+year) dates, cumul_uniq, unique_per_day, new_users = cumulative_users(stats, year) total = cumul_uniq[-1] if year != "": year = " in " + year pyplot_init() - pyplot.bar(dates, unique_per_day, label='Unique contributors') - pyplot.bar(dates, new_users, label='First time contributor via MapComplete') + pyplot.fill_between(dates, unique_per_day, label='Unique contributors') + pyplot.fill_between(dates, new_users, label='First time contributor via MapComplete') pyplot.legend() pyplot.title("Unique contributors" + year + ' with MapComplete (' + str(total) + ' contributors)') pyplot.ylabel("Number of unique contributors") @@ -161,6 +162,7 @@ theme_remappings = { def create_theme_breakdown(stats, year="", user=None, columnIndex=3): + print("Creating theme breakdown "+year) themeCounts = {} for row in stats: if not row[0].startswith(year): @@ -212,8 +214,13 @@ def gen_theme_breakdown_graphs(contents, user=None): for year in range(2020, currentYear + 1): create_theme_breakdown(contents, str(year), user) +def changes_per_theme_daily(contents): + hist = {} + for row in contents: + + def main(): - print("Creating logs...") + print("Creating graphs...") with open('stats.csv', newline='') as csvfile: stats = list(csv.reader(csvfile, delimiter=',', quotechar='"')) print("Found "+str(len(stats))+" changesets") @@ -222,4 +229,6 @@ def main(): print("All done!") +# pyplot.fill_between(range(0,5), [1,2,3,3,2],) +# pyplot.show() main() diff --git a/Docs/Tools/stats.csv b/Docs/Tools/stats.csv index 5971d10..93731e2 100644 --- a/Docs/Tools/stats.csv +++ b/Docs/Tools/stats.csv @@ -2843,9 +2843,26 @@ "2021-03-08", "Pieter Nuytinck", "en", "bookcases", "MapComplete 0.4.9", 2, 15 "2021-03-08", "whturner", "en", "benches", "MapComplete 0.4.9", 3, 9 "2021-03-08", "WinstonSmith", "en", "cyclofix", "MapComplete 0.5.5", 18, 38 +"2021-03-09", "Alexmol", "en", "charging_stations", "MapComplete 0.5.6", 0, 3 "2021-03-09", "benetj", "ca", "aed", "MapComplete 0.5.5", 1, 3 "2021-03-09", "benetj", "en", "charging_stations", "MapComplete 0.5.5", 0, 6 "2021-03-09", "benetj", "en", "maps", "MapComplete 0.5.5", 2, 1 "2021-03-09", "whturner", "en", "benches", "MapComplete 0.4.9", 4, 12 -"2021-03-09", "WinstonSmith", "en", "cyclofix", "MapComplete 0.5.6", 2, 1 "2021-03-09", "WinstonSmith", "en", "cyclofix", "MapComplete 0.5.6", 2, 4 +"2021-03-09", "WinstonSmith", "en", "cyclofix", "MapComplete 0.5.6", 38, 51 +"2021-03-10", "Alexmol", "en", "charging_stations", "MapComplete 0.5.6", 0, 1 +"2021-03-10", "Alexmol", "en", "charging_stations", "MapComplete 0.5.6", 0, 1 +"2021-03-10", "Awo", "en", "trees", "MapComplete 0.4.9", 0, 10 +"2021-03-10", "steven lauwers", "nl", "https://raw.githubusercontent.com/osmbe/play/master/mapcomplete/geveltuinen/geveltuinen.json", "MapComplete 0.5.5-unlocked", 0, 1 +"2021-03-10", "steven lauwers", "nl", "https://raw.githubusercontent.com/osmbe/play/master/mapcomplete/geveltuinen/geveltuinen.json", "MapComplete 0.5.5-unlocked", 0, 1 +"2021-03-10", "steven lauwers", "nl", "https://raw.githubusercontent.com/osmbe/play/master/mapcomplete/geveltuinen/geveltuinen.json", "MapComplete 0.5.5-unlocked", 1, 8 +"2021-03-10", "WinstonSmith", "en", "cyclofix", "MapComplete 0.5.6", 11, 14 +"2021-03-11", "Koen Rijnsent", "en", "artworks", "MapComplete 0.5.6", 1, 5 +"2021-03-11", "Koen Rijnsent", "en", "artworks", "MapComplete 0.5.6", 1, 5 +"2021-03-11", "Koen Rijnsent", "en", "artworks", "MapComplete 0.5.6", 2, 2 +"2021-03-11", "MAGONA", "en", "trees", "MapComplete 0.4.9", 1, 2 +"2021-03-11", "MAGONA", "en", "trees", "MapComplete 0.4.9", 9, 37 +"2021-03-11", "Pieter Vander Vennet", "nl", "buurtnatuur", "MapComplete 0.5.6", 0, 1 +"2021-03-11", "whturner", "en", "benches", "MapComplete 0.5.6", 3, 4 +"2021-03-11", "WinstonSmith", "en", "cyclofix", "MapComplete 0.5.6", 9, 16 +"2021-03-12", "CordeB", "nl", "wandelknooppunten", "MapComplete 0.5.6", 0, 6 diff --git a/Models/Constants.ts b/Models/Constants.ts index 3ac9a48..6d39bbb 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import { Utils } from "../Utils"; export default class Constants { - public static vNumber = "0.5.6"; + public static vNumber = "0.5.7"; // The user journey states thresholds when a new feature gets unlocked public static userJourney = { diff --git a/State.ts b/State.ts index c7f9625..5710ed6 100644 --- a/State.ts +++ b/State.ts @@ -76,7 +76,7 @@ export default class State { /** The latest element that was selected */ - public readonly selectedElement = new UIEventSource(undefined) + public readonly selectedElement = new UIEventSource(undefined, "Selected element") public readonly featureSwitchUserbadge: UIEventSource; diff --git a/UI/Base/ScrollableFullScreen.ts b/UI/Base/ScrollableFullScreen.ts index e2b5886..2567676 100644 --- a/UI/Base/ScrollableFullScreen.ts +++ b/UI/Base/ScrollableFullScreen.ts @@ -14,12 +14,13 @@ export default class ScrollableFullScreen extends UIElement { private _component: UIElement; private _fullscreencomponent: UIElement; - constructor(title: (() => UIElement), content: (() => UIElement), isShown: UIEventSource = new UIEventSource(false)) { + constructor(title: ((mode: string) => UIElement), content: ((mode: string) => UIElement), + isShown: UIEventSource = new UIEventSource(false)) { super(); this.isShown = isShown; - this._component = this.BuildComponent(title(), content(), isShown); - this._fullscreencomponent = this.BuildComponent(title(), content(), isShown); + this._component = this.BuildComponent(title("desktop"), content("desktop"), isShown); + this._fullscreencomponent = this.BuildComponent(title("mobile"), content("mobile"), isShown); this.dumbMode = false; const self = this; isShown.addCallback(isShown => { diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts index 30432cf..0e56101 100644 --- a/UI/Popup/FeatureInfoBox.ts +++ b/UI/Popup/FeatureInfoBox.ts @@ -17,7 +17,9 @@ export default class FeatureInfoBox extends ScrollableFullScreen { tags: UIEventSource, layerConfig: LayerConfig ) { - super(() => FeatureInfoBox.GenerateTitleBar(tags, layerConfig),() => FeatureInfoBox.GenerateContent(tags, layerConfig)); + super((mode:string) => FeatureInfoBox.GenerateTitleBar(tags, layerConfig, mode), + (mode:string) => FeatureInfoBox.GenerateContent(tags, layerConfig, mode)); + if (layerConfig === undefined) { throw "Undefined layerconfig"; } @@ -46,7 +48,8 @@ export default class FeatureInfoBox extends ScrollableFullScreen { } private static GenerateContent(tags: UIEventSource, - layerConfig: LayerConfig): UIElement { + layerConfig: LayerConfig, + mode: string): UIElement { let questionBox: UIElement = undefined; diff --git a/UI/Popup/TagRenderingQuestion.ts b/UI/Popup/TagRenderingQuestion.ts index 3375fd5..4242951 100644 --- a/UI/Popup/TagRenderingQuestion.ts +++ b/UI/Popup/TagRenderingQuestion.ts @@ -38,7 +38,8 @@ export default class TagRenderingQuestion extends UIElement { constructor(tags: UIEventSource, configuration: TagRenderingConfig, afterSave?: () => void, - cancelButton?: UIElement) { + cancelButton?: UIElement + ) { super(tags); this._tags = tags; this._configuration = configuration; diff --git a/UI/SubstitutedTranslation.ts b/UI/SubstitutedTranslation.ts index 8e67f6c..cd132fd 100644 --- a/UI/SubstitutedTranslation.ts +++ b/UI/SubstitutedTranslation.ts @@ -6,9 +6,11 @@ import Combine from "./Base/Combine"; import State from "../State"; import {FixedUiElement} from "./Base/FixedUiElement"; import SpecialVisualizations from "./SpecialVisualizations"; +import {Utils} from "../Utils"; export class SubstitutedTranslation extends UIElement { - private static cachedTranslations: Map, SubstitutedTranslation>> = new Map, SubstitutedTranslation>>(); + private static cachedTranslations: + Map, SubstitutedTranslation>>> = new Map, SubstitutedTranslation>>>(); private readonly tags: UIEventSource; private readonly translation: Translation; private content: UIElement[]; @@ -32,20 +34,26 @@ export class SubstitutedTranslation extends UIElement { this.SetClass("w-full") } + private static GenerateMap(){ + return new Map, SubstitutedTranslation>() + } + private static GenerateSubCache(){ + return new Map, SubstitutedTranslation>>(); + } + public static construct( translation: Translation, tags: UIEventSource): SubstitutedTranslation { - if (!this.cachedTranslations.has(translation)) { - this.cachedTranslations.set(translation, new Map, SubstitutedTranslation>()); - } - const innerMap = this.cachedTranslations.get(translation); + + /* let cachedTranslations = Utils.getOrSetDefault(SubstitutedTranslation.cachedTranslations, SubstitutedTranslation.GenerateSubCache); + const innerMap = Utils.getOrSetDefault(cachedTranslations, translation, SubstitutedTranslation.GenerateMap); const cachedTranslation = innerMap.get(tags); if (cachedTranslation !== undefined) { return cachedTranslation; - } + }*/ const st = new SubstitutedTranslation(translation, tags); - innerMap.set(tags, st); + // innerMap.set(tags, st); return st; }