Compare commits

..

No commits in common. "458b5c45b7e87b084c62a415e86fd8573685769e" and "aae0790c27eb4d93edb061afe86db8a6a5117a7d" have entirely different histories.

7 changed files with 50 additions and 275 deletions

View File

@ -10,9 +10,8 @@ Data source from : https://github.com/pomber/covid19
## Features : ## Features :
- Maths functions : Exp, pow, Logistic
- sync X axis at a value - sync X axis at a value
- reset - reset (broken, need reload page too)
- set a limit for y axis - set a limit for y axis
- select first and last day - select first and last day
- select data source (confirmed, deaths, recovered) - select data source (confirmed, deaths, recovered)

View File

@ -3,7 +3,14 @@
## First production : ## First production :
User Local Presets (N) OK load data source
OK git clean
vuejs prod
hosting
Save user config to local
reset mode
Charts modes: Charts modes:
- Country day decal - Country day decal

2
doc.md
View File

@ -3,8 +3,6 @@
# Changelog # Changelog
v0.04 Fix reset
v0.03 maths functions
v0.02 sync x axis v0.02 sync x axis
v0.01 repack, data auto loading v0.01 repack, data auto loading

View File

@ -106,26 +106,9 @@
ymax: 0, ymax: 0,
syncSince: 0, syncSince: 0,
resetConfig: false, resetConfig: false,
math: {
exp: {
display: false,
factor: 6.5,
dayPrev: 26
},
pow: {
display: false,
factor: 3,
dayPrev: 5
},
logi: {
display: false,
factor:0.15,
dayPrev: 42
},
},
}, },
countriesConfig: { countriesConfig: {
selected: [{name: "France"}, {name: "Italy"},{name:"Spain"},{name:"United Kingdom"}], selected: [{name: "France"}, {name: "Italy"}],
basePalette: "tolRainbowColor" basePalette: "tolRainbowColor"
}, },
} }
@ -137,13 +120,13 @@
props: { props: {
source: String, source: String,
}, },
data () { return { data: () => ({
drawer: true, drawer: true,
title: 'Cov Charts', title: 'Cov Charts',
allData: {}, allData: {},
chartWidth: 500, chartWidth: 500,
chartConfig: Object.assign({},defaultUserConfig.chartConfig), chartConfig: defaultUserConfig.chartConfig,
countriesConfig:Object.assign({}, defaultUserConfig.countriesConfig), countriesConfig: defaultUserConfig.countriesConfig,
configLists: { configLists: {
scaleList: ['log', 'linear'], scaleList: ['log', 'linear'],
typesList: ['confirmed', 'deaths', 'recovered'], typesList: ['confirmed', 'deaths', 'recovered'],
@ -154,7 +137,7 @@
//all: Object.keys(AllData).sort(), //all: Object.keys(AllData).sort(),
}, },
debug: false, debug: false,
}}, }),
watch: { watch: {
drawer() { drawer() {
console.log('dd', this.drawer) console.log('dd', this.drawer)
@ -189,108 +172,26 @@
uc = JSON.parse(uc) uc = JSON.parse(uc)
this.countriesConfig = uc.countriesConfig this.countriesConfig = uc.countriesConfig
this.chartConfig = uc.chartConfig this.chartConfig = uc.chartConfig
this.ccc("loadConfig storage")
} else { } else {
this.countriesConfig = Object.assign({},defaultUserConfig.countriesConfig) this.countriesConfig = defaultUserConfig.countriesConfig
this.chartConfig = Object.assign({},defaultUserConfig.chartConfig) this.chartConfig = defaultUserConfig.chartConfig
this.ccc("loadConfig default")
} }
}, },
saveConfig() { saveConfig() {
this.ccc("saveConfig")
let userConfig = {countriesConfig: this.countriesConfig, chartConfig: this.chartConfig} let userConfig = {countriesConfig: this.countriesConfig, chartConfig: this.chartConfig}
localStorage.setItem('userConfig', JSON.stringify(userConfig)) localStorage.setItem('userConfig', JSON.stringify(userConfig))
}, },
resetConfig() { resetConfig() {
localStorage.setItem('userConfig', 'null') localStorage.setItem('userConfig', 'null')
this.ccc("resetConfig")
this.loadConfig() this.loadConfig()
}, },
ccc(a, b) { ccc(a, b) {
if (this.debug) console.log(a, b?b:'') if (this.debug) console.log(a, b)
}, },
addMathFunctions(cdata, ymax) {
let cc = this.chartConfig.math
// Pow
if (cc.pow.display) {
cdata.push(this.calcFunction(cdata,
'pow3',
'#ffc500',
i => limit(Math.pow(i - parseInt(cc.pow.dayPrev), parseFloat(cc.pow.factor)), 1, ymax)
))
}
// Exp
if (cc.exp.display) {
cdata.push(this.calcFunction(cdata,
'exp',
'#fd1e00',
i => limit(Math.exp((i + parseInt(cc.exp.dayPrev)) / parseFloat(cc.exp.factor)), 1, ymax)
))
}
if (cc.logi.display) {
// Logistic function
let L = ymax
let k = parseFloat(cc.logi.factor)
let xo = parseInt(cc.logi.dayPrev)
cdata.push(this.calcFunction(cdata,
'logistic',
'rgb(253,130,0)',
//i => limit(L / (1 + Math.exp(Math.E, -k*(i - xo))), 1, 60000)
i => limit(L / (1 + Math.exp(-k * (i - xo))), 0, ymax)
))
}
return cdata
},
calcFunction(cdata, name, color, callback) {
return {
country: name,
color: color,
isMaths: true,
list: cdata[0].list.map((day, id) => {
return {
confirmed: callback(id),
date: day.date
}
})
}
},
calculateLog(cdata, ymax) {
console.log(' calculateLog',)
let max = ymax
let dayDecal = 2
let pointsCount = cdata[0].list.length
let e = Math.log(max)
let step = e / pointsCount
step , dayDecal;
let getY = i => {
i = i === 0 ? 0.5 : i
let value = Math.exp((i + dayDecal) * step)
//let value = Math.pow((i), 3)
return value < max ? value : undefined
}
let pointList = cdata[0].list.map((d, i) => {
return {
confirmed: getY(i),
date: d.date
}
})
let log = {
country: "log",
color: '#FFCC00',
list: pointList
}
cdata.push(log)
return cdata
},
}, },
computed: { computed: {
syncSinceInt() { syncSinceInt() {
@ -304,7 +205,6 @@
let formatedData = [] let formatedData = []
const addSomeDays = false const addSomeDays = false
let ymax = 0
this.countriesConfig.selected.map((country) => { this.countriesConfig.selected.map((country) => {
@ -346,19 +246,14 @@
} }
} }
// Get ymax // // Get ymax
// filtered.map(d => {
filtered.map(d => { // ymax = d[this.dataSelected] > ymax ? d[this.dataSelected] : ymax
ymax = d[this.chartConfig.typeSelected] > ymax ? d[this.chartConfig.typeSelected] : ymax // })
})
country.list = filtered country.list = filtered
formatedData.push(country) formatedData.push(country)
}) })
formatedData = this.addMathFunctions(formatedData, ymax)
return formatedData return formatedData
} }
} }
@ -372,23 +267,9 @@
font-size: 12px; font-size: 12px;
} }
input, select, .v-input, .v-label { input, select, .v-input {
font-size: 13px; font-size: 12px;
} }
.v-list--dense .v-list-item {
min-height: 20px;
}
.v-list--dense .v-list-item .v-list-item__content {
padding: 2px 0;
}
.v-list-item__action{
margin: 8px 0;
}
.v-text-field.v-text-field--solo .v-input__control {
min-height: 20px;
}
</style> </style>

View File

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<v-list dense> <v-list dense >
<v-list-item> <v-list-item>
<v-list-item-action>Scale</v-list-item-action> <v-list-item-action>Scale</v-list-item-action>
@ -17,6 +17,7 @@
</v-list-item> </v-list-item>
<v-list-item> <v-list-item>
<v-list-item-action>Type</v-list-item-action> <v-list-item-action>Type</v-list-item-action>
<v-list-item-content> <v-list-item-content>
@ -56,7 +57,7 @@
</v-list-item> </v-list-item>
<v-list-item> <v-list-item>
<v-list-item-action>Sync X</v-list-item-action> <v-list-item-action>Sync X </v-list-item-action>
<v-list-item-content> <v-list-item-content>
<v-text-field <v-text-field
class="numField" class="numField"
@ -72,7 +73,7 @@
<v-list-item> <v-list-item>
<v-list-item-action>Limit Y</v-list-item-action> <v-list-item-action>Limit Y </v-list-item-action>
<v-list-item-content> <v-list-item-content>
<v-text-field <v-text-field
class="numField" class="numField"
@ -86,105 +87,6 @@
</v-list-item> </v-list-item>
<v-list-item>
<v-list-item-action>
<b>Maths Functions</b>
</v-list-item-action>
</v-list-item>
<v-list-item>
<v-list-item-action>
<v-switch
label=" Exp"
v-model="configs.math.exp.display"
color="blue-grey darken-1"
></v-switch>
</v-list-item-action>
<v-list-item-content v-if="configs.math.exp.display">
F:
<v-text-field
class="numFieldsm"
v-model="configs.math.exp.factor"
label="Factor"
solo
hide-details
single-line
/>
D:
<v-text-field
class="numFieldsm"
v-model="configs.math.exp.dayPrev"
label="Days"
solo
hide-details
single-line
/>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-action>
<v-switch
label=" Pow"
v-model="configs.math.pow.display"
color="blue-grey darken-1"
></v-switch>
</v-list-item-action>
<v-list-item-content v-if="configs.math.pow.display">
F:
<v-text-field
class="numFieldsm"
v-model="configs.math.pow.factor"
solo
hide-details
single-line
/>
D:
<v-text-field
class="numFieldsm"
v-model="configs.math.pow.dayPrev"
solo
hide-details
single-line
/>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-action>
<v-switch
label=" Logi"
v-model="configs.math.logi.display"
color="blue-grey darken-1"
></v-switch>
</v-list-item-action>
<v-list-item-content v-if="configs.math.logi.display">
F:
<v-text-field
class="numFieldsm"
v-model="configs.math.logi.factor"
solo
hide-details
single-line
/>
D:
<v-text-field
class="numFieldsm"
v-model="configs.math.logi.dayPrev"
solo
hide-details
single-line
/>
</v-list-item-content>
</v-list-item>
<v-list-item> <v-list-item>
<v-list-item-action></v-list-item-action> <v-list-item-action></v-list-item-action>
<v-list-item-content> <v-list-item-content>
@ -194,8 +96,6 @@
</v-btn> </v-btn>
</v-list-item-content> </v-list-item-content>
</v-list-item> </v-list-item>
</v-list> </v-list>
</div> </div>
</template> </template>
@ -209,11 +109,12 @@
props: ['configs', 'configLists'], props: ['configs', 'configLists'],
components: {Counter}, components: {Counter},
data() { data() {
return {} return {
}
}, },
watch: { watch:{
'configs.syncSince': function (value) { 'configs.syncSince': function(value){
if (!(value > 0)) { if ( ! (value > 0 ) ){
this.configs.syncSince = 0 this.configs.syncSince = 0
} }
} }
@ -223,7 +124,7 @@
this.configs.resetConfig = true this.configs.resetConfig = true
} }
}, },
computed: {} computed: { }
} }
</script> </script>
@ -238,9 +139,4 @@
max-width: 50%; max-width: 50%;
} }
.numFieldsm {
max-width: 50px;
}
</style> </style>

View File

@ -18,7 +18,7 @@
</div> </div>
<div v-for="(cinfo,id) in countriesData" :key="'ns'+id"> <div v-for="(cinfo,id) in countriesData" :key="'ns'+id">
<div class="chartBlock" v-if="!cinfo.isMaths"> <div class="chartBlock">
<BarChartSingle <BarChartSingle
:dataType="dtype" :dataType="dtype"
:country="cinfo.name" :country="cinfo.name"

View File

@ -1,7 +1,7 @@
<template> <template>
<div :class="'counter '+ classname"> <div :class="'counter '+ classname">
<button @click="click(-1)" class="bleft">-</button> <button @click="click(-1)" class="bleft">-</button>
<span>{{input}}</span> <span>{{value}}</span>
<button @click="click(1)" class="bright">+</button> <button @click="click(1)" class="bright">+</button>
</div> </div>
</template> </template>
@ -17,16 +17,18 @@
classname: {type: String, default: 'themeGreen'}, classname: {type: String, default: 'themeGreen'},
}, },
data() { data() {
return {} return {
value: this.input,
}
}, },
methods: { methods: {
click(dirfactor) { click(dirfactor) {
let input = this.input + (dirfactor * this.inc) this.value = this.value + (dirfactor * this.inc)
if (input > this.max) input = this.max if (this.value > this.max) this.value = this.max
if (input < this.min) input = this.min if (this.value < this.min) this.value = this.min
this.$emit('input', input) this.$emit('input', this.value)
} }
}, }
} }
</script> </script>
@ -42,18 +44,16 @@
padding: 0; padding: 0;
width: 15px; width: 15px;
line-height: 15px; line-height: 15px;
/*/margin: 0 px 3 px 0 px 3 px;*/ /*/margin: 0 px 3 px 0 px 3 px;*/
} }
.bleft, .bright { .bleft, .bright {
border: 0px solid red; border: 0px solid red;
border-radius: 5px; border-radius: 5px;
} }
.bleft { .bleft {
margin-right: 3px; margin-right: 3px;
} }
.bright { .bright {
margin-left: 3px; margin-left: 3px;
} }
@ -61,17 +61,14 @@
.themeGreen.counter { .themeGreen.counter {
border: 1px solid #2c3e50; border: 1px solid #2c3e50;
background: #d3e3e0; background: #d3e3e0;
color: white; color:white;
} }
.themeGreen.counter button { .themeGreen.counter button {
background: #d3e3e0; background: #d3e3e0;
} }
.themeGreen .bleft { .themeGreen .bleft {
border-right: 1px solid #2c3e50; border-right: 1px solid #2c3e50;
} }
.themeGreen .bright { .themeGreen .bright {
border-left: 1px solid #2c3e50; border-left: 1px solid #2c3e50;
} }
@ -79,19 +76,16 @@
.themeGrey.counter { .themeGrey.counter {
border: 0px solid #8ecaf9; border: 0px solid #8ecaf9;
background: inherit; background: inherit;
color: white; color:white;
} }
.themeGrey.counter button { .themeGrey.counter button {
background: #767676; background: #767676;
width: 18px; width: 18px;
line-height: 18px; line-height: 18px;
} }
.themeGrey .bleft { .themeGrey .bleft {
border-right: 0px solid #8ecaf9; border-right: 0px solid #8ecaf9;
} }
.themeGrey .bright { .themeGrey .bright {
border-left: 0px solid #8ecaf9; border-left: 0px solid #8ecaf9;
} }