Yes, my observable is here : https://observablehq.com/@reyman/covid
Sorry for the code quality, i’m discovering little by little all the power of d3/observable, but i have some difficulties with widget building.
I build a little api of my own to serve data and metadata about different sources of covid19 data, with some added statistics.
My idea was to use metadata answer to build the different option widget :
The return of metadata REST call
return {
'data':
{"ecdc":{
"description" : "ECDC data",
"type" : [{
"name" : "cum",
"label" : "Données cumulées",
"options":[]
},{
"name": "daily",
"label": "Données journalières",
"options":[
{"label":"Moyenne mobile des décés sur 3 jours",
"value":"rolling_deaths"}]
}]}
,"etalab": {
"description": "Etalab french data consolidated",
"type": [{
"name": "cum",
"label": "Données cumulées",
"options": []
}]}
}}
As you could see, i have two type of covid19 data :
- cumulated for : ECDC data
- day by day for : ECDC data and Etalab institute data
In my published observable, user could switch between sources, type of data (cumulated or daily if exists) that regenerate an url, and corresponding data are fetch from server.
I also want to display wiget to choose options if they exists, this is the options array in metadata response.
For etalab, no options and only cumulated data :
For Ecdc data, cumulated data with no options :
For Ecdc data, daily data with one option :
I probably add new option later for data.
So as you could see, i need to manage different combinaisons of widget possibilities using if/else.
viewof optionsCheckbox = checkbox(checkbox_data)
- sources = ecdc or etalab
- typeOfGraph = daily or cum
- metadata_opt return options available if any
checkbox_data = {
if (metadata_opt(sources,typeOfGraph).length) {
return {
title: "",
description: "",
options: metadata_opt(sources,typeOfGraph),
submit: false
}
}
else { return undefined}
}
Using this code, my idea was to check if options exist or not in metadata data. If this option exist, i display the widget and collect the corresponding data, if not exist, do nothing.
optionSeries
return data used by chart to display lines. If one serie, i have one line, if many series, i have multi-lines. Actually i also compute the growth of deaths and growth of cases for each dataset (i need to report that on metadata response on server as new options for cum and daily dataset … )
For daily data, if have three series of data available in optionSeries
, so three lines (growth death, growth cases, rolling deaths ). For cumulated data, i only have two series available. (growth death and growth cases).
Idea was to filter these series based on checkbox options selected by user, perhaps displaying others widget/options if needed, like window size for rolling window mean computation…
optionSeriesFiltered = {
if (optionsCheckbox !== undefined )
{ return optionSeries.map(s => s.filter( d => optionsCheckbox.includes(d.name))).filter(e => e.length)}
else
{
return "bla"
}
}
Problem was when optionCheckbox is undefined, this code FAILED, because :
- 1 - viewof optionsCheckbox = TypeError: options is undefined
- 2 - optionSeriesFiltered = RuntimeError: optionsCheckbox could not be resolved
- 3 - finaly, chart = RuntimeError: optionSeriesFiltered could not be resolved
I need to rethink my workflow to better handle all of this.