New graphs; disable optimazation
							
								
								
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						|  | @ -9,3 +9,5 @@ assets/generated/* | ||||||
| /*.html | /*.html | ||||||
| !/index.html | !/index.html | ||||||
| .parcel-cache | .parcel-cache | ||||||
|  | Docs/Tools/stats.*.json | ||||||
|  | Docs/Tools/stats.csv | ||||||
|  |  | ||||||
|  | @ -74,7 +74,7 @@ export default class TagRenderingConfig { | ||||||
|             } |             } | ||||||
|             if(this.freeform.addExtraTags){ |             if(this.freeform.addExtraTags){ | ||||||
|                 const usedKeys = new And(this.freeform.addExtraTags).usedKeys(); |                 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}`; |                     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}`; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
| Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 576 KiB | 
| Before Width: | Height: | Size: 205 KiB After Width: | Height: | Size: 496 KiB | 
| Before Width: | Height: | Size: 203 KiB After Width: | Height: | Size: 644 KiB | 
| Before Width: | Height: | Size: 273 KiB After Width: | Height: | Size: 273 KiB | 
| Before Width: | Height: | Size: 271 KiB After Width: | Height: | Size: 269 KiB | 
| Before Width: | Height: | Size: 544 KiB After Width: | Height: | Size: 550 KiB | 
| Before Width: | Height: | Size: 764 KiB After Width: | Height: | Size: 760 KiB | 
|  | @ -111,14 +111,15 @@ def pyplot_init(): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def create_usercount_graphs(stats, year="", show=False): | 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) |     dates, cumul_uniq, unique_per_day, new_users = cumulative_users(stats, year) | ||||||
|     total = cumul_uniq[-1] |     total = cumul_uniq[-1] | ||||||
| 
 | 
 | ||||||
|     if year != "": |     if year != "": | ||||||
|         year = " in " + year |         year = " in " + year | ||||||
|     pyplot_init() |     pyplot_init() | ||||||
|     pyplot.bar(dates, unique_per_day, label='Unique contributors') |     pyplot.fill_between(dates, unique_per_day, label='Unique contributors') | ||||||
|     pyplot.bar(dates, new_users, label='First time contributor via MapComplete') |     pyplot.fill_between(dates, new_users, label='First time contributor via MapComplete') | ||||||
|     pyplot.legend() |     pyplot.legend() | ||||||
|     pyplot.title("Unique contributors" + year + ' with MapComplete (' + str(total) + ' contributors)') |     pyplot.title("Unique contributors" + year + ' with MapComplete (' + str(total) + ' contributors)') | ||||||
|     pyplot.ylabel("Number of unique contributors") |     pyplot.ylabel("Number of unique contributors") | ||||||
|  | @ -161,6 +162,7 @@ theme_remappings = { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def create_theme_breakdown(stats, year="", user=None, columnIndex=3): | def create_theme_breakdown(stats, year="", user=None, columnIndex=3): | ||||||
|  |     print("Creating theme breakdown "+year) | ||||||
|     themeCounts = {} |     themeCounts = {} | ||||||
|     for row in stats: |     for row in stats: | ||||||
|         if not row[0].startswith(year): |         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): |     for year in range(2020, currentYear + 1): | ||||||
|         create_theme_breakdown(contents, str(year), user) |         create_theme_breakdown(contents, str(year), user) | ||||||
| 
 | 
 | ||||||
|  | def changes_per_theme_daily(contents): | ||||||
|  |     hist = {} | ||||||
|  |     for row in contents: | ||||||
|  |          | ||||||
|  |          | ||||||
| def main(): | def main(): | ||||||
|     print("Creating logs...") |     print("Creating graphs...") | ||||||
|     with open('stats.csv', newline='') as csvfile: |     with open('stats.csv', newline='') as csvfile: | ||||||
|         stats = list(csv.reader(csvfile, delimiter=',', quotechar='"')) |         stats = list(csv.reader(csvfile, delimiter=',', quotechar='"')) | ||||||
|         print("Found "+str(len(stats))+" changesets") |         print("Found "+str(len(stats))+" changesets") | ||||||
|  | @ -222,4 +229,6 @@ def main(): | ||||||
|     print("All done!") |     print("All done!") | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | # pyplot.fill_between(range(0,5),  [1,2,3,3,2],) | ||||||
|  | # pyplot.show() | ||||||
| main() | main() | ||||||
|  |  | ||||||
|  | @ -2843,9 +2843,26 @@ | ||||||
| "2021-03-08", "Pieter Nuytinck", "en", "bookcases", "MapComplete 0.4.9", 2, 15 | "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", "whturner", "en", "benches", "MapComplete 0.4.9", 3, 9 | ||||||
| "2021-03-08", "WinstonSmith", "en", "cyclofix", "MapComplete 0.5.5", 18, 38 | "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", "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", "charging_stations", "MapComplete 0.5.5", 0, 6 | ||||||
| "2021-03-09", "benetj", "en", "maps", "MapComplete 0.5.5", 2, 1 | "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", "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", 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 | ||||||
|  |  | ||||||
| 
 | 
|  | @ -2,7 +2,7 @@ import { Utils } from "../Utils"; | ||||||
| 
 | 
 | ||||||
| export default class Constants { | 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
 |     // The user journey states thresholds when a new feature gets unlocked
 | ||||||
|     public static userJourney = { |     public static userJourney = { | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								State.ts
									
										
									
									
									
								
							
							
						
						|  | @ -76,7 +76,7 @@ export default class State { | ||||||
|     /** |     /** | ||||||
|      The latest element that was selected |      The latest element that was selected | ||||||
|      */ |      */ | ||||||
|     public readonly selectedElement = new UIEventSource<any>(undefined) |     public readonly selectedElement = new UIEventSource<any>(undefined, "Selected element") | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     public readonly featureSwitchUserbadge: UIEventSource<boolean>; |     public readonly featureSwitchUserbadge: UIEventSource<boolean>; | ||||||
|  |  | ||||||
|  | @ -14,12 +14,13 @@ export default class ScrollableFullScreen extends UIElement { | ||||||
|     private _component: UIElement; |     private _component: UIElement; | ||||||
|     private _fullscreencomponent: UIElement; |     private _fullscreencomponent: UIElement; | ||||||
| 
 | 
 | ||||||
|     constructor(title: (() => UIElement), content: (() => UIElement), isShown: UIEventSource<boolean> = new UIEventSource<boolean>(false)) { |     constructor(title: ((mode: string) => UIElement), content: ((mode: string) => UIElement),  | ||||||
|  |                 isShown: UIEventSource<boolean> = new UIEventSource<boolean>(false)) { | ||||||
|         super(); |         super(); | ||||||
|         this.isShown = isShown; |         this.isShown = isShown; | ||||||
| 
 | 
 | ||||||
|         this._component = this.BuildComponent(title(), content(), isShown); |         this._component = this.BuildComponent(title("desktop"), content("desktop"), isShown); | ||||||
|         this._fullscreencomponent = this.BuildComponent(title(), content(), isShown); |         this._fullscreencomponent = this.BuildComponent(title("mobile"), content("mobile"), isShown); | ||||||
|         this.dumbMode = false; |         this.dumbMode = false; | ||||||
|         const self = this; |         const self = this; | ||||||
|         isShown.addCallback(isShown => { |         isShown.addCallback(isShown => { | ||||||
|  |  | ||||||
|  | @ -17,7 +17,9 @@ export default class FeatureInfoBox extends ScrollableFullScreen { | ||||||
|         tags: UIEventSource<any>, |         tags: UIEventSource<any>, | ||||||
|         layerConfig: LayerConfig |         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) { |         if (layerConfig === undefined) { | ||||||
|             throw "Undefined layerconfig"; |             throw "Undefined layerconfig"; | ||||||
|         } |         } | ||||||
|  | @ -46,7 +48,8 @@ export default class FeatureInfoBox extends ScrollableFullScreen { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private static GenerateContent(tags: UIEventSource<any>, |     private static GenerateContent(tags: UIEventSource<any>, | ||||||
|                                    layerConfig: LayerConfig): UIElement { |                                    layerConfig: LayerConfig, | ||||||
|  |                                    mode: string): UIElement { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         let questionBox: UIElement = undefined; |         let questionBox: UIElement = undefined; | ||||||
|  |  | ||||||
|  | @ -38,7 +38,8 @@ export default class TagRenderingQuestion extends UIElement { | ||||||
|     constructor(tags: UIEventSource<any>, |     constructor(tags: UIEventSource<any>, | ||||||
|                 configuration: TagRenderingConfig, |                 configuration: TagRenderingConfig, | ||||||
|                 afterSave?: () => void, |                 afterSave?: () => void, | ||||||
|                 cancelButton?: UIElement) { |                 cancelButton?: UIElement         | ||||||
|  |     ) { | ||||||
|         super(tags); |         super(tags); | ||||||
|         this._tags = tags; |         this._tags = tags; | ||||||
|         this._configuration = configuration; |         this._configuration = configuration; | ||||||
|  |  | ||||||
|  | @ -6,9 +6,11 @@ import Combine from "./Base/Combine"; | ||||||
| import State from "../State"; | import State from "../State"; | ||||||
| import {FixedUiElement} from "./Base/FixedUiElement"; | import {FixedUiElement} from "./Base/FixedUiElement"; | ||||||
| import SpecialVisualizations from "./SpecialVisualizations"; | import SpecialVisualizations from "./SpecialVisualizations"; | ||||||
|  | import {Utils} from "../Utils"; | ||||||
| 
 | 
 | ||||||
| export class SubstitutedTranslation extends UIElement { | export class SubstitutedTranslation extends UIElement { | ||||||
|     private static cachedTranslations: Map<Translation, Map<UIEventSource<any>, SubstitutedTranslation>> = new Map<Translation, Map<UIEventSource<any>, SubstitutedTranslation>>(); |     private static cachedTranslations:  | ||||||
|  |         Map<string, Map<Translation, Map<UIEventSource<any>, SubstitutedTranslation>>> = new Map<string, Map<Translation, Map<UIEventSource<any>, SubstitutedTranslation>>>(); | ||||||
|     private readonly tags: UIEventSource<any>; |     private readonly tags: UIEventSource<any>; | ||||||
|     private readonly translation: Translation; |     private readonly translation: Translation; | ||||||
|     private content: UIElement[]; |     private content: UIElement[]; | ||||||
|  | @ -32,20 +34,26 @@ export class SubstitutedTranslation extends UIElement { | ||||||
|         this.SetClass("w-full") |         this.SetClass("w-full") | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private static GenerateMap(){ | ||||||
|  |         return new Map<UIEventSource<any>, SubstitutedTranslation>() | ||||||
|  |     } | ||||||
|  |     private static GenerateSubCache(){ | ||||||
|  |         return new  Map<Translation, Map<UIEventSource<any>, SubstitutedTranslation>>(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|     public static construct( |     public static construct( | ||||||
|         translation: Translation, |         translation: Translation, | ||||||
|         tags: UIEventSource<any>): SubstitutedTranslation { |         tags: UIEventSource<any>): SubstitutedTranslation { | ||||||
|         if (!this.cachedTranslations.has(translation)) { |          | ||||||
|             this.cachedTranslations.set(translation, new Map<UIEventSource<any>, SubstitutedTranslation>()); |        /* let cachedTranslations = Utils.getOrSetDefault(SubstitutedTranslation.cachedTranslations, SubstitutedTranslation.GenerateSubCache); | ||||||
|         } |         const innerMap = Utils.getOrSetDefault(cachedTranslations, translation, SubstitutedTranslation.GenerateMap); | ||||||
|         const innerMap = this.cachedTranslations.get(translation); |  | ||||||
| 
 | 
 | ||||||
|         const cachedTranslation = innerMap.get(tags); |         const cachedTranslation = innerMap.get(tags); | ||||||
|         if (cachedTranslation !== undefined) { |         if (cachedTranslation !== undefined) { | ||||||
|             return cachedTranslation; |             return cachedTranslation; | ||||||
|         } |         }*/ | ||||||
|         const st = new SubstitutedTranslation(translation, tags); |         const st = new SubstitutedTranslation(translation, tags); | ||||||
|         innerMap.set(tags, st); |        // innerMap.set(tags, st);
 | ||||||
|         return st; |         return st; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||