Published
Edited
Jul 8, 2020
Fork of MAP
Insert cell
md`# MAP`
Insert cell
Insert cell
Insert cell
totalOutput = d3
.nest()
.rollup(function(d) {
return d.map(function(c) {
return {
key: c.key,
total: d3.sum(c.values.map(x => parseInt(x.cases)))
};
});
})
.entries(countriesValue)
Insert cell
map.update(dataToday)
Insert cell
Insert cell
Insert cell
function getDataByCountryID(id) {
const countryData = countriesValueWithTotalCases.filter(
country => country.key === id
)[0].values,
data = [];
for (let element of countryData) {
let obj = {
date: d3.autoType({ date: formatDate(element.dateRep) }),
cases: element.cases,
deaths: element.deaths
};
data.push(obj);
}
return data;
}
Insert cell
function formatDate(dateString) {
const date = new Date(
dateString.slice(-4),
dateString.slice(3, 5),
dateString.slice(0, 2)
);
const dateForm =
date.getFullYear() +
'-' +
('0' + (date.getMonth() + 1)).slice(-2) +
'-' +
('0' + date.getDate()).slice(-2);
return dateForm;
}
Insert cell
countriesValueWithTotalCases = {
let totalCasesWorldArray = [];
for (let element of countriesValue) {
let valuesObjectWorld = {
key: element.key,
values: calculateTotalCases(element.values)
};
totalCasesWorldArray.push(valuesObjectWorld);
}
return totalCasesWorldArray;
}
Insert cell
countriesValueByDayWithTotalCases = d3
.nest()
.key(function(d) {
return d.key;
})
.entries(flattedCountriesValueWithTotalCases)
Insert cell
calculateTotalCases = array => {
let valuesArray = [];
let indexOfValuesArray = 0;
for (let i = array.length - 1; i >= 0; i--) {
let today = array[i];

if (indexOfValuesArray > 0) {
let cases = parseInt(today.cases) +
parseInt(valuesArray[indexOfValuesArray - 1].cases),
deaths = parseInt(today.deaths) +
parseInt(valuesArray[indexOfValuesArray - 1].deaths);
let valuesObject = {
dateRep: today.dateRep,
cases: cases,
deaths: deaths,
casesPer100: getCasesPer100(today.countriesAndTerritories, cases),
deathsPer100: getCasesPer100(today.countriesAndTerritories, deaths)
};
valuesArray[indexOfValuesArray] = valuesObject;
} else {
let cases = parseInt(today.cases), deaths = parseInt(today.deaths);
let valuesObject = {
dateRep: today.dateRep,
cases: cases,
deaths: deaths,
casesPer100: getCasesPer100(today.countriesAndTerritories, cases),
deathsPer100: getCasesPer100(today.countriesAndTerritories, deaths)
};
valuesArray[indexOfValuesArray] = valuesObject;
}
indexOfValuesArray++;
}
return valuesArray;
}
Insert cell
Insert cell
function getCasesPer100(country, totalCases) {
let casesPer = 0 , deathsPer = 0, countryPop;
countryPop = countriesPop.filter( x => x.country === country);
//ignore after comma numbers because the difference of one has no effect on the user.
casesPer = Math.round(totalCases / (countryPop[0].pop / 100000))

return casesPer
}
Insert cell
getNameByID = y =>
countries.filter(x => x.code == y)[0] != null
? countries.filter(x => x.code == y)[0].name
: ""
Insert cell
Insert cell
md`### Appendix`
Insert cell
d3 = require('d3')
Insert cell
import { Scrubber } from "@mbostock/scrubber"
Insert cell
md`#### Data preparing`
Insert cell
curve = d3.curveLinear
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
Insert cell
Insert cell
//import data
filedata = d3.csvParse(await FileAttachment("data-set@3.csv").text())
Insert cell
//a TopoJSON file containing the geometry collections countries and land(1:110m small scale)
worldAtlas = FileAttachment("world-atlas-110m.json").json()
Insert cell
Insert cell
countriesPop = countriesValue.map( x => ({ country: x.key, pop: parseInt(x.values[0].popData2019) }));
Insert cell
countries = d3.csv(urlCountrieIDs, d3.autoType);
Insert cell
urlCountrieIDs = FileAttachment("country-ids.csv").url()
Insert cell
days = countriesValueByDay.map(c => c.key)
Insert cell
countriesValueByDay = d3
.nest()
.key(function(d) {
return d.dateRep;
})
.entries(filedata)
.sort(
(a, b) =>
d3.ascending(a.key.slice(6), b.key.slice(6)) || //sort by year
d3.ascending(a.key.slice(3), b.key.slice(3)) || // sort by mobth
d3.ascending(a.key.slice(0), b.key.slice(0)) // sort by day
)
Insert cell
Insert cell
md`#### Topojson`
Insert cell
topojson = require('topojson')
Insert cell
// transforms latitudes and longitudes on the surface of a sphere into positions on a plane.
projection = d3
.geoNaturalEarth1() //The Natural Earth projection.
.rotate([0, 0]) // rotate the sphere
.precision(0.1) // set the precision for the graticule (default 2,5)
.fitSize([width, height], { type: "Sphere" }) //dynamically fitting a d3 topojson map to a resizeable container
Insert cell
//mathematical description of the map
//topojson feature explanation: https://www.freecodecamp.org/forum/t/d3-topojson-feature-explanation/235396/2
topojsonDataSet = topojson.feature(worldAtlas, worldAtlas.objects.countries)
.features
Insert cell
path = d3.geoPath().projection(projection)
Insert cell
md`#### Parameters`
Insert cell
height = width <= 500 ? Math.round(width / 1.3) : Math.round(width / 1.8)
Insert cell
margin = 10;
Insert cell
radius = 70
Insert cell
koef = 0.00005
Insert cell
minRad = width / 1000
Insert cell
closeButtonWidth = 40
Insert cell
chartMargin = ({ top: 20, right: 30, bottom: 30, left: 60 })
Insert cell
closeButtonHeight = 15
Insert cell
chartWidth = 320
Insert cell
chartHeight = 200
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more