Published
Edited
Sep 11, 2020
Insert cell
Insert cell
Insert cell
Insert cell
draw({ w: mobileWidth })
Insert cell
Insert cell
stringency_mw = render(mobileWidth)
Insert cell
stringency_cw = render(contentWidth)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
rawData = d3.csvParse(await FileAttachment("fra@9.csv").text())
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
dataGap = 1
Insert cell
Insert cell
Insert cell
firstAvailableDate = d3.min(data, d => d[xDatumName])
Insert cell
evenEarlierDate = new Date(firstAvailableDate.valueOf()).setDate(
firstAvailableDate.getDate() - dataGap
)
Insert cell
countryNameTranslation = ({
China: "China",
Canada: "Kanada",
Denmark: "Dänemark",
France: "Frankreich",
Germany: "Deutschland",
India: "Indien",
Ireland: "Irland",
Japan: "Japan",
Norway: "Norwegen",
Singapore: "Singapur",
"South Korea": "Südkorea",
Spain: "Spanien",
Sweden: "Schweden",
Switzerland: "Schweiz",
"United Kingdom": "Grossbritannien",
"United States": "USA",
Australia: "Australien",
Austria: "Österreich",
Italy: "Italien",
Romania: "Rumänien",
Brazil: "Brasilien",
Mexico: "Mexiko",
"United Arab Emirates": "VAE",
Russia: "Russland",
Indonesia: "Indonesien",
Netherlands: "Niederlande",
"New Zealand": "Neuseeland",
"Saudi Arabia": "Saudiarabien",
Turkey: "Türkei",
Finland: "Finnland",
"South Africa": "Südafrika",
Thailand: "Thailand",
Chile: "Chile",
Belgium: "Belgien",
"Czech Republic": "Tschechien",
Poland: "Poland",
Romania: "Rumänien",
"Belarus": 'Weissrussland',
"Lithuania": "Litauen",
Estonia: "Estland",
"Bulgaria": "Bulgarien",
Croatia: "Kroatien",
Poland: "Polen",
Iceland: "Island",
Slovenia: "Slowenien",
Latvia: "Lettland",
Luxembourg: "Luxemburg",
Hungary: "Ungarn",
Cyprus: "Zyprus",
Serbia: "Serbien",
Moldova: "Moldawien",
"Bosnia and Herzegovina": "Bosnien",
Albania: "Albanien",
Greece: "Griechenland",
Georgia: "Georgien",
"Slovak Republic": "Slowakei",
"Kazakhstan": "Kasachstan"
})
Insert cell
function translateCountry(name) {
if (countryNameTranslation[name]) {
return countryNameTranslation[name];
}

return name;
}
Insert cell
md`### Formatting`
Insert cell
Insert cell
formatVeryRound = new Intl.NumberFormat('fr-CH', {
maximumFractionDigits: 0
}).format
Insert cell
formatShortDate = new Intl.DateTimeFormat('de-CH', {
month: 'numeric',
day: 'numeric'
}).format
Insert cell
md`### Drawing functions`
Insert cell
gradientStops = [0, 25, 50, 75, 100]
Insert cell
function svgScaffold(conf) {
const colorScale = colorScaleFactory(data);
const yScale = yScaleFactory(data, conf);
const range = colorScale.range();
const radius = verticalRhythm / 3;

return svg`
<svg width="${conf.w}px" height="${conf.h}px" viewBox="0 0 ${conf.w} ${
conf.h
}" style="background-color: #ffffff; font-family: ${font}; font-size: ${fontSize}; font-variant-numeric: tabular-nums; shape-rendering: crispEdges">

<defs>
<linearGradient id="stringencyGrad">
${gradientStops.map(
stop =>
svg`<stop offset="${stop}%" stop-color="${colorScale(
gradientPositionScale(100 - stop)
)}" />`
)}
</linearGradient>
</defs>

<g id="legend" fill="${textColor}">
<text x="0" y="12">${colorScale.domain()[1]}%</text>
<g transform="translate(40)">
<rect width="${6 * verticalRhythm}" height="14" fill="url('#stringencyGrad')" />
</g>
<text x="165" y="12">${colorScale.domain()[0]}%</text>

<g transform="translate(200)" shape-rendering="geometricPrecision">
<circle transform="translate(${radius} ${14 -
radius})" fill="${colorScale.unknown()}" r="${radius}" />
<text x="${radius * 2 + 5}" y="12">keine Angaben</text>
</g>

</g>

<g id="end-values" fill="#6e6e7e">
${countryList.map(country => {
const val = data.find(
el => el[yDatumName] === country && mostCurrentDate - el[xDatumName] === 0
)[valueName];
return svg`
<text text-anchor="end" x="${conf.w}" y="${yScale(country) +
yScale.bandwidth() -
2}">${formatVeryRound(val)}%</text>
`;
})}
</g>

</svg>`;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md`### Scales`
Insert cell
function xScaleFactory(d, conf) {
const evenEarlierDate = new Date(firstAvailableDate.valueOf());
evenEarlierDate.setDate(firstAvailableDate.getDate() - dataGap);

return d3
.scaleTime()
.domain([evenEarlierDate, mostCurrentDate])
.range([conf.left, conf.w - conf.right]);
}
Insert cell
function yScaleFactory(data, conf) {
return d3
.scaleBand()
.domain(countryList)
.range([conf.h - conf.bottom, conf.top])
.paddingInner(0.3);
}
Insert cell
function colorScaleFactory() {
return (
d3
.scaleSequential(d3.interpolateHcl('#edece1', '#d64b47'))
// Use the extent of the data, or …
.domain(d3.extent(data, d => d[valueName]))
// use the extent of the index
//.domain([0, 100])
// .domain([33.333444, 66.6666])
.nice()
.unknown('#abb4f0')
);
}
Insert cell
gradientPositionScale = d3
.scaleLinear()
.domain([0, 100])
.range(colorScaleFactory(data).domain())
Insert cell
md`## Teaser Image`
Insert cell
draw({ w: 400 })
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