New graphs; disable optimazation
4
.gitignore
vendored
|
@ -8,4 +8,6 @@ assets/generated/*
|
||||||
/*.webmanifest
|
/*.webmanifest
|
||||||
/*.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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|