covcharts/src/App.vue

216 lines
5.5 KiB
Vue

<template>
<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-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)"
/>
<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>
</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'
let limit = (value, min, max) => {
return value > max ? max : value < min ? min : value
}
limit()
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;
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
}
}
}
</script>
<style>
html, body {
height: 100%;
margin: 0;
font-size: 12px;
}
input, select, .v-input {
font-size: 12px;
}
</style>