Published
Edited
May 4, 2021
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
steppedChartNorm = (variable, title) => {
let data = rawFrance.map(d => ({
date: d.date,
value: parseFloat(d[variable]) - floor(d, variable),
floor: floor(d, variable)
}))

let min = d3.min(data, d => d.value)
let max = d3.max(data, d => d.value)

let y = d3.scaleLinear()
.domain([min, max]).nice()
.range([height-margin.bottom, margin.top])
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height])


steps.map(date =>{
svg.append('svg:line')
.attr('x1', x(new Date(date)))
.attr('y1', d3.max(y.range()))
.attr('x2', x(new Date(date)))
.attr('y2', d3.min(y.range()))
.attr('stroke', '#ddd')
})
svg.append('path')
.attr('fill', 'black')
.attr("d", areaNormPos(data, y))

svg.append('path')
.attr('fill', '#ccc')
.attr("d", areaNormNeg(data, y))

let xAxis = g => g
.attr("transform", `translate(0,${height-margin.bottom})`)
.call(d3.axisBottom(x).ticks(d3.timeMonth).tickSizeOuter(0))

let yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))

svg.append("g")
.call(xAxis);

svg.append("g")
.call(yAxis);

svg.append('text')
.attr("text-anchor", "end")
.style('font', '13px times')
.attr("x", width - margin.right)
.attr("y", height-5)
.text(title)
return svg.node()
}
Insert cell
Insert cell
// https://fr.wikipedia.org/wiki/Pand%C3%A9mie_de_Covid-19_en_France

steps = [
'2020-03-05', // première interdiction de rassemblements
'2020-03-17', // confinement
'2020-05-11', // déconfinement
'2020-07-11', // levée de la majorité des mesures
'2020-10-17', // couvre-feu 21h
'2020-10-30', // fermeture des magasins
'2020-11-28', // réouverture des magasins
'2020-12-14', // interdiction de déplacement soir et nut
'2021-04-03', // interdiction de déplacement + fermeture des magasins + fermeture des écoles/collègues/lycées
'2021-05-03', // réouvertures et fin interdiction de déplacement
'2021-05-19',
'2021-06-21',
'2021-06-30'
]
Insert cell
Insert cell
variables = {
let keys = Object.keys(rawFrance[0])
let hide = [ 'date' ]
return keys.filter(e=> !hide.includes(e))
}
Insert cell
floors('dc_tot')
Insert cell
// construction des différentes étapes
floors = (v) => d3.pairs(steps).map((step)=>{
let start = step[0]
let end = step[1]
let value = days.get(start) ? parseFloat(days.get(start)[0][v]): 0
return { start, end, value }
})
Insert cell
Insert cell
// calcul des valeurs de base en fonction des étapes
function floor(p, variable){
let f = 0
floors(variable).map(ff=>{
if(p.date >= ff.start && p.date <= ff.end){
f = ff.value
}
})
return f
}
Insert cell
function steppedChart(variable){
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height])

steps.map(date =>{
svg.append('svg:line')
.attr('x1', x(new Date(date)))
.attr('y1', d3.max(y.range()))
.attr('x2', x(new Date(date)))
.attr('y2', d3.min(y.range()))
.attr('stroke', '#ddd')
})

floors(variable).map(d=>{
svg.append('svg:line')
.attr('x1', x(new Date(d.start)))
.attr('y1', y(d.value))
.attr('x2', x(new Date(d.end)))
.attr('y2', y(d.value))
.attr('stroke', '#ddd')
})
svg.append('path')
.attr('fill', 'black')
.attr("d", areaPos(rawFrance, variable))

svg.append('path')
.attr('fill', '#ccc')
.attr("d", areaNeg(rawFrance, variable))

let xAxis = g => g
.attr("transform", `translate(0,${height-margin.bottom})`)
.call(d3.axisBottom(x).ticks(d3.timeMonth).tickSizeOuter(0))

let yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))

svg.append("g")
.call(xAxis);

svg.append("g")
.call(yAxis);

return svg.node()
}
Insert cell
areaPos = (data, variable) => {
let area = d3.area()
.defined( p => !isNaN(parseFloat(p[variable])) )
.x ( p => x(new Date(p.date)) )
.y0 ( p => y(floor(p, variable)) )
.y1 ( p => y(d3.max([p[variable], floor(p, variable)])))
return area(data)
}
Insert cell
areaNeg = (data, variable) => {
let area = d3.area()
.defined( p => !isNaN(parseFloat(p[variable])) )
.x ( p => x(new Date(p.date)))
.y0 ( p => y(floor(p, variable)))
.y1 ( p => y(d3.min([p[variable], floor(p, variable)])) )

return area(data)
}
Insert cell
areaNormPos = (data, y) => {
let area = d3.area()
.defined( p => !isNaN(parseFloat(p.value)) )
.x ( p => x(new Date(p.date)) )
.y0 ( y(0) )
.y1 ( p => y(d3.max([p.value, 0])) )
return area(data)
}

Insert cell
areaNormNeg = (data, y) => {
let area = d3.area()
.defined( p => !isNaN(parseFloat(p.value)) )
.x ( p => x(new Date(p.date)) )
.y0 ( y(0) )
.y1 ( p => y(d3.min([p.value, 0])) )
return area(data)
}
Insert cell
x = d3.scaleTime()
.domain([new Date(2020, 2, 1, 0), new Date(2021, 4, 3)]).nice()
.range([margin.left, width - margin.right])
Insert cell
y = {
let max = d3.max(rawFrance, d => parseFloat(d[variable]))
let min = d3.min(rawFrance, d => parseFloat(d[variable]))
return d3.scaleLinear()
.domain([min, max]).nice()
.range([height-margin.bottom, margin.top])
}
Insert cell
height = 500
Insert cell
sourceFrance = 'https://www.data.gouv.fr/fr/datasets/r/f335f9ea-86e3-4ffa-9684-93c009d5e617'
Insert cell
mutable lastUpdate = null
Insert cell
rawFrance = {
mutable lastUpdate = new Date()
return d3.csv(sourceFrance)
}
Insert cell
margin = {
return {
left: 40,
right: 30,
top: 20,
bottom: 35
}
}
Insert cell
d3 = require('d3', 'd3-time', 'd3-time-format')
Insert cell
import {Select} from "@observablehq/inputs"
Insert cell
import {datasetCard} from '@taniki/datagouvfr-oembed'
Insert cell
import {tweet} from "@mbostock/tweet"
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