local config with reset (buggy)
This commit is contained in:
parent
c4db1aa587
commit
429d0d59a9
27
brain.md
27
brain.md
@ -3,21 +3,26 @@
|
||||
|
||||
## First production :
|
||||
|
||||
load data source
|
||||
OK load data source
|
||||
OK git clean
|
||||
vuejs prod
|
||||
git clean
|
||||
hosting
|
||||
|
||||
|
||||
load data source
|
||||
local storage :
|
||||
save all data
|
||||
save timeStamp
|
||||
|
||||
on load
|
||||
if delay > 1hour : reload data
|
||||
|
||||
|
||||
Save user config to local
|
||||
reset mode
|
||||
|
||||
Charts modes:
|
||||
- Country day decal
|
||||
- sync on first day at xxx
|
||||
- divide by country population
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Data source
|
||||
|
||||
Data source :
|
||||
https://github.com/pomber/covid19
|
||||
|
400
src/App.vue
400
src/App.vue
@ -1,215 +1,253 @@
|
||||
<template>
|
||||
<v-app id="inspire">
|
||||
<v-app id="inspire">
|
||||
|
||||
<v-app-bar app clipped-left>
|
||||
<v-app-bar-nav-icon @click.stop="drawer = !drawer"/>
|
||||
<v-toolbar-title>{{title}}</v-toolbar-title>
|
||||
</v-app-bar>
|
||||
<v-app-bar app clipped-left>
|
||||
<v-app-bar-nav-icon @click.stop="drawer = !drawer"/>
|
||||
<v-toolbar-title>{{title}}</v-toolbar-title>
|
||||
</v-app-bar>
|
||||
|
||||
<v-navigation-drawer
|
||||
v-model="drawer"
|
||||
app
|
||||
clipped
|
||||
stateless
|
||||
>
|
||||
<v-navigation-drawer
|
||||
v-model="drawer"
|
||||
app
|
||||
clipped
|
||||
stateless
|
||||
>
|
||||
|
||||
<ChartConfig
|
||||
:configs="chartConfig"
|
||||
:configLists="configLists"
|
||||
v-model="chartConfig"
|
||||
/>
|
||||
|
||||
<CountriesConfig
|
||||
:lists="countriesLists"
|
||||
:configs="countriesConfig"
|
||||
/>
|
||||
|
||||
<DataLoader
|
||||
v-model="allData"
|
||||
></DataLoader>
|
||||
|
||||
</v-navigation-drawer>
|
||||
|
||||
<v-content>
|
||||
<v-container class="sfill-height" fluid>
|
||||
<v-row align="center" justify="center" id="maincontent" ref="maincontent">
|
||||
<v-col class="shrink">
|
||||
|
||||
|
||||
<MultiCountryChart
|
||||
:countries="countriesData"
|
||||
:scaleType="chartConfig.scaleSelected"
|
||||
:dataType="chartConfig.typeSelected"
|
||||
:width="chartWidth"
|
||||
:height="chartWidth * (2/3)"
|
||||
<ChartConfig
|
||||
:configs="chartConfig"
|
||||
:configLists="configLists"
|
||||
/>
|
||||
|
||||
<MultiBarChartSingle
|
||||
:countriesData="countriesData"
|
||||
:scaleType="chartConfig.scaleSelected"
|
||||
:width="260"
|
||||
:height="100"
|
||||
<CountriesConfig
|
||||
:lists="countriesLists"
|
||||
:configs="countriesConfig"
|
||||
/>
|
||||
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-content>
|
||||
<DataLoader
|
||||
v-model="allData"
|
||||
></DataLoader>
|
||||
|
||||
<v-footer app>
|
||||
</v-navigation-drawer>
|
||||
|
||||
<v-content>
|
||||
<v-container class="sfill-height" fluid>
|
||||
<v-row align="center" justify="center" id="maincontent" ref="maincontent">
|
||||
<v-col class="shrink">
|
||||
|
||||
|
||||
<MultiCountryChart
|
||||
:countries="countriesData"
|
||||
:scaleType="chartConfig.scaleSelected"
|
||||
:dataType="chartConfig.typeSelected"
|
||||
:width="chartWidth"
|
||||
:height="chartWidth * (2/3)"
|
||||
/>
|
||||
|
||||
<MultiBarChartSingle
|
||||
:countriesData="countriesData"
|
||||
:scaleType="chartConfig.scaleSelected"
|
||||
:width="260"
|
||||
:height="100"
|
||||
/>
|
||||
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-content>
|
||||
|
||||
<v-footer app>
|
||||
<span>
|
||||
Using <a href="https://vuejs.org/" target="_blank">Vuejs</a>
|
||||
and <a href="https://d3js.org/" target="_blank">d3</a> -
|
||||
<a href="https://github.com/pomber/covid19" target="_blank">Data source</a>
|
||||
</span>
|
||||
</v-footer>
|
||||
</v-app>
|
||||
</v-footer>
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
//import AllData from '../data/timeseries.json'
|
||||
import ChartConfig from './components/ChartConfig'
|
||||
import CountriesConfig from './components/CountriesConfig'
|
||||
import MultiCountryChart from './components/d3/MultiCountryChart'
|
||||
import MultiBarChartSingle from './components/MultiBarChartSingle'
|
||||
import DataLoader from './components/DataLoader'
|
||||
//import AllData from '../data/timeseries.json'
|
||||
import ChartConfig from './components/ChartConfig'
|
||||
import CountriesConfig from './components/CountriesConfig'
|
||||
import MultiCountryChart from './components/d3/MultiCountryChart'
|
||||
import MultiBarChartSingle from './components/MultiBarChartSingle'
|
||||
import DataLoader from './components/DataLoader'
|
||||
|
||||
|
||||
let limit = (value, min, max) => {
|
||||
return value > max ? max : value < min ? min : value
|
||||
}
|
||||
limit()
|
||||
let limit = (value, min, max) => {
|
||||
return value > max ? max : value < min ? min : value
|
||||
}
|
||||
limit()
|
||||
|
||||
function formatDate(date) {
|
||||
var d = new Date(date),
|
||||
function formatDate(date) {
|
||||
var d = new Date(date),
|
||||
month = '' + (d.getMonth() + 1),
|
||||
day = '' + d.getDate(),
|
||||
year = d.getFullYear();
|
||||
|
||||
if (month.length < 2)
|
||||
month = '0' + month;
|
||||
if (day.length < 2)
|
||||
day = '0' + day;
|
||||
if (month.length < 2)
|
||||
month = '0' + month;
|
||||
if (day.length < 2)
|
||||
day = '0' + day;
|
||||
|
||||
return [year, month, day].join('-');
|
||||
}
|
||||
|
||||
|
||||
export default {
|
||||
name: 'AppVuetify',
|
||||
components: {ChartConfig, CountriesConfig, MultiCountryChart, MultiBarChartSingle, DataLoader},
|
||||
props: {
|
||||
source: String,
|
||||
},
|
||||
data: () => ({
|
||||
drawer: true,
|
||||
title: 'Cov Charts',
|
||||
allData: {},
|
||||
chartConfig: {
|
||||
typeSelected: 'confirmed',
|
||||
scaleSelected: 'linear',
|
||||
dayStart: 30,
|
||||
dayEnd: 0,
|
||||
ymax: 0,
|
||||
},
|
||||
chartWidth: 500,
|
||||
configLists: {
|
||||
scaleList: ['log', 'linear'],
|
||||
typesList: ['confirmed', 'deaths', 'recovered'],
|
||||
},
|
||||
countriesConfig: {
|
||||
selected: [{name: "France"}, {name: "Italy"}],
|
||||
basePalette: "tolRainbowColor"
|
||||
|
||||
},
|
||||
countriesLists: {
|
||||
top: ['Belgium', 'Sweden', 'France', 'Japan', 'Korea, South', 'Russia', 'Germany', 'Spain', 'Italy', 'China', 'United Kingdom', 'US'],
|
||||
// Todo list of all countries using localstorage
|
||||
//all: Object.keys(AllData).sort(),
|
||||
}
|
||||
|
||||
}),
|
||||
watch: {
|
||||
drawer() {
|
||||
console.log('dd', this.drawer)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$vuetify.theme.dark = true
|
||||
},
|
||||
mounted() {
|
||||
// Todo find a better way to get size
|
||||
//this.chartWidth = this.$refs.maincontent.clientWidth * 2 / 3
|
||||
|
||||
this.chartWidth = 800
|
||||
},
|
||||
computed: {
|
||||
|
||||
countriesData() {
|
||||
|
||||
if (!('France' in this.allData)) {
|
||||
return []
|
||||
}
|
||||
|
||||
let formatedData = []
|
||||
const addSomeDays = false
|
||||
|
||||
this.countriesConfig.selected.map((country) => {
|
||||
|
||||
let cdata = JSON.parse(JSON.stringify(this.allData[country.name]))
|
||||
let itemsCount = cdata.length
|
||||
let filtered = cdata.filter((e, i) =>
|
||||
i >= (this.chartConfig.dayStart - 1) &&
|
||||
i < (itemsCount - this.chartConfig.dayEnd))
|
||||
|
||||
if (addSomeDays) {
|
||||
// Adding addDays data points
|
||||
let datebase = new Date(filtered.slice(-1)[0].date)
|
||||
for (let i = 0; i < this.chartConfig.addDays; i++) {
|
||||
let dd = new Date(datebase.getFullYear(), datebase.getMonth(), datebase.getDate() + i);
|
||||
filtered.push({
|
||||
date: formatDate(dd),
|
||||
deaths: undefined,
|
||||
recovered: undefined,
|
||||
confirmed: undefined,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (this.chartConfig.ymax > 0) {
|
||||
filtered = filtered.map((d) => {
|
||||
this.configLists.typesList.map(e => {
|
||||
d[e] = d[e] > this.chartConfig.ymax ? this.chartConfig.ymax : d[e]
|
||||
})
|
||||
return d
|
||||
})
|
||||
}
|
||||
// // Get ymax
|
||||
// filtered.map(d => {
|
||||
// ymax = d[this.dataSelected] > ymax ? d[this.dataSelected] : ymax
|
||||
// })
|
||||
|
||||
country.list = filtered
|
||||
formatedData.push(country)
|
||||
})
|
||||
|
||||
return formatedData
|
||||
}
|
||||
return [year, month, day].join('-');
|
||||
}
|
||||
|
||||
|
||||
const defaultUserConfig = {
|
||||
chartConfig: {
|
||||
typeSelected: 'confirmed',
|
||||
scaleSelected: 'linear',
|
||||
dayStart: 30,
|
||||
dayEnd: 0,
|
||||
ymax: 0,
|
||||
resetConfig: false,
|
||||
},
|
||||
countriesConfig: {
|
||||
selected: [{name: "France"}, {name: "Italy"}],
|
||||
basePalette: "tolRainbowColor"
|
||||
},
|
||||
}
|
||||
defaultUserConfig
|
||||
|
||||
export default {
|
||||
name: 'AppVuetify',
|
||||
components: {ChartConfig, CountriesConfig, MultiCountryChart, MultiBarChartSingle, DataLoader},
|
||||
props: {
|
||||
source: String,
|
||||
},
|
||||
data: () => ({
|
||||
drawer: true,
|
||||
title: 'Cov Charts',
|
||||
allData: {},
|
||||
chartWidth: 500,
|
||||
chartConfig: defaultUserConfig.chartConfig,
|
||||
countriesConfig: defaultUserConfig.countriesConfig,
|
||||
configLists: {
|
||||
scaleList: ['log', 'linear'],
|
||||
typesList: ['confirmed', 'deaths', 'recovered'],
|
||||
},
|
||||
countriesLists: {
|
||||
top: ['Belgium', 'Sweden', 'France', 'Japan', 'Korea, South', 'Russia', 'Germany', 'Spain', 'Italy', 'China', 'United Kingdom', 'US'],
|
||||
// Todo list of all countries using localstorage
|
||||
//all: Object.keys(AllData).sort(),
|
||||
},
|
||||
}),
|
||||
watch: {
|
||||
drawer() {
|
||||
console.log('dd', this.drawer)
|
||||
},
|
||||
countriesConfig: {
|
||||
handler: function () {
|
||||
this.saveConfig()
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
chartConfig: {
|
||||
handler: function (val) {
|
||||
val.resetConfig ? this.resetConfig() : this.saveConfig()
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$vuetify.theme.dark = true
|
||||
},
|
||||
mounted() {
|
||||
// Todo find a better way to get size
|
||||
//this.chartWidth = this.$refs.maincontent.clientWidth * 2 / 3
|
||||
this.chartWidth = 800
|
||||
this.loadConfig()
|
||||
|
||||
},
|
||||
methods: {
|
||||
loadConfig() {
|
||||
|
||||
let uc = localStorage.getItem('userConfig')
|
||||
if (uc && uc !== 'null') {
|
||||
uc = JSON.parse(uc)
|
||||
this.countriesConfig = uc.countriesConfig
|
||||
this.chartConfig = uc.chartConfig
|
||||
} else {
|
||||
this.countriesConfig = defaultUserConfig.countriesConfig
|
||||
this.chartConfig = defaultUserConfig.chartConfig
|
||||
}
|
||||
},
|
||||
saveConfig() {
|
||||
let userConfig = {countriesConfig: this.countriesConfig, chartConfig: this.chartConfig}
|
||||
localStorage.setItem('userConfig', JSON.stringify(userConfig))
|
||||
},
|
||||
resetConfig() {
|
||||
localStorage.setItem('userConfig', 'null')
|
||||
this.loadConfig()
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
countriesData() {
|
||||
|
||||
if (!('France' in this.allData)) {
|
||||
return []
|
||||
}
|
||||
|
||||
let formatedData = []
|
||||
const addSomeDays = false
|
||||
|
||||
this.countriesConfig.selected.map((country) => {
|
||||
|
||||
let cdata = JSON.parse(JSON.stringify(this.allData[country.name]))
|
||||
let itemsCount = cdata.length
|
||||
let filtered = cdata.filter((e, i) =>
|
||||
i >= (this.chartConfig.dayStart - 1) &&
|
||||
i < (itemsCount - this.chartConfig.dayEnd))
|
||||
|
||||
if (addSomeDays) {
|
||||
// Adding addDays data points
|
||||
let datebase = new Date(filtered.slice(-1)[0].date)
|
||||
for (let i = 0; i < this.chartConfig.addDays; i++) {
|
||||
let dd = new Date(datebase.getFullYear(), datebase.getMonth(), datebase.getDate() + i);
|
||||
filtered.push({
|
||||
date: formatDate(dd),
|
||||
deaths: undefined,
|
||||
recovered: undefined,
|
||||
confirmed: undefined,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (this.chartConfig.ymax > 0) {
|
||||
filtered = filtered.map((d) => {
|
||||
this.configLists.typesList.map(e => {
|
||||
d[e] = d[e] > this.chartConfig.ymax ? this.chartConfig.ymax : d[e]
|
||||
})
|
||||
return d
|
||||
})
|
||||
}
|
||||
// // Get ymax
|
||||
// filtered.map(d => {
|
||||
// ymax = d[this.dataSelected] > ymax ? d[this.dataSelected] : ymax
|
||||
// })
|
||||
|
||||
country.list = filtered
|
||||
formatedData.push(country)
|
||||
})
|
||||
|
||||
return formatedData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
input, select, .v-input {
|
||||
font-size: 12px;
|
||||
}
|
||||
input, select, .v-input {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<v-list dense>
|
||||
<v-list dense >
|
||||
|
||||
<v-list-item>
|
||||
<v-list-item-action> Scale</v-list-item-action>
|
||||
@ -70,6 +70,15 @@
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item>
|
||||
<v-list-item-action></v-list-item-action>
|
||||
<v-list-item-content>
|
||||
<v-btn @click="resetConfig()"
|
||||
x-small
|
||||
>Reset
|
||||
</v-btn>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</div>
|
||||
</template>
|
||||
@ -83,16 +92,15 @@
|
||||
props: ['configs', 'configLists'],
|
||||
components: {Counter},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
watch: {
|
||||
config(prev,neww){
|
||||
if (prev.ymax !== neww.ymax){
|
||||
console.log('new y',neww.ymax)
|
||||
}
|
||||
return {
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
methods: {
|
||||
resetConfig() {
|
||||
this.configs.resetConfig = true
|
||||
}
|
||||
},
|
||||
computed: { }
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -103,8 +111,8 @@
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.ymax{
|
||||
max-width:50%;
|
||||
.ymax {
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
</style>
|
@ -17,8 +17,7 @@
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
|
||||
<v-list-item v-for="(cinfo,id) in configs.selected" :key="id" class="countryLine">
|
||||
<v-list-item v-for="(cinfo,id) in getSelected" :key="id" class="countryLine">
|
||||
<v-list-item-action>
|
||||
<v-btn fab dark x-small
|
||||
@click="removeCountry(cinfo.name)">
|
||||
@ -60,15 +59,11 @@
|
||||
// TODO : change the base list used for countries
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.setColors();
|
||||
},
|
||||
watch: {
|
||||
selected() {
|
||||
if (this.selected === '') return // prevent the reset in this function
|
||||
if (this.configs.selected.map(d => d.name).indexOf(this.selected) === -1) {
|
||||
this.configs.selected.push({name: this.selected})
|
||||
this.setColors()
|
||||
}
|
||||
this.addCountry = !this.addCountry
|
||||
this.selected = ''
|
||||
@ -90,6 +85,11 @@
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
// Add colors with selected
|
||||
getSelected(){
|
||||
this.setColors()
|
||||
return this.configs.selected
|
||||
},
|
||||
getActiveCountries() {
|
||||
// TODO filter out selected countries
|
||||
return []
|
||||
|
@ -91,11 +91,9 @@
|
||||
},
|
||||
mounted() {
|
||||
this.drawAxis()
|
||||
console.log('dataType', this.dataType)
|
||||
},
|
||||
watch: {
|
||||
scaleType(neww) {
|
||||
console.log('', neww)
|
||||
scaleType() {
|
||||
this.drawAxis()
|
||||
},
|
||||
countries() {
|
||||
|
Loading…
Reference in New Issue
Block a user