Published
Edited
Sep 16, 2020
15 forks
1 star
Insert cell
Insert cell
Insert cell
max = 8000000
Insert cell
Insert cell
conf = {
return {
countries: [
{ label: "Italien", color: "#cfcfd6", offsetY: 0, offsetX: 0 },
{ label: "Südkorea", color: "#cfcfd6", offsetY: -15, offsetX: -40 },
{ label: "USA", color: "#cfcfd6", offsetY: 0, offsetX: 0 },
{ label: "Schweiz", color: "#cfcfd6", offsetY: 0, offsetX: 0 },
{ label: "Russland", color: "#cfcfd6", offsetY: 3, offsetX: 0 },
{ label: "Indien", color: "#cfcfd6", offsetY: 2, offsetX: 0 },
{ label: "Mexiko", color: "#1D8534", offsetY: 10, offsetX: -60 },
{ label: "Brasilien", color: "#a9cf00", offsetY: -4, offsetX: 0 },
{ label: "Peru", color: "#ae3143", offsetY: 8, offsetX: 0 },
{ label: "Kolumbien", color: "#8440a3", offsetY: -4, offsetX: 1 },
{ label: "Chile", color: "#da467d", offsetY: 0, offsetX: 0 }
],
labels: [100, 1000, 10000, 100000, 1000000]
};
}
Insert cell
Insert cell
svgToCanvas(await drawMw(), 3)
Insert cell
function drawMw() {
const svgNode = svg`
<svg width="${mwConf.width}px" height="${mwConf.height + 35}" viewBox="0 0 ${
mwConf.width
} ${mwConf.height + 35}" >

<g id="dayLabels"></g>
<g id="yLabels"></g>
<g id="lines"></g>
${getLabelXAxisAt(mwConf.height + 25)}

</svg>`;

dayLabels(svgNode, mwConf);
yLabels(svgNode, mwConf);
conf.countries.forEach(c => {
lineForCountry(c, svgNode, mwConf);
labelForCountry(c, svgNode, mwConf);
});
return svgNode;
}
Insert cell
mwConf = {
return {
width: 380,
height: 450,
left: 72,
bottom: 25,
right: 50
};
}
Insert cell
Insert cell
svgToCanvas(await drawCw(), 3)
Insert cell
function drawCw() {
const svgNode = svg`
<svg width="${cwConf.width}px" height="${cwConf.height + 35}" viewBox="0 0 ${
cwConf.width
} ${cwConf.height + 35}" >

<g id="dayLabels"></g>
<g id="yLabels"></g>
<g id="lines"></g>
${getLabelXAxisAt(cwConf.height + 25)}

</svg>`;

dayLabels(svgNode, cwConf);
yLabels(svgNode, cwConf);
conf.countries.forEach(c => {
lineForCountry(c, svgNode, cwConf);
labelForCountry(c, svgNode, cwConf);
});
return svgNode;
}
Insert cell
cwConf = {
return {
width: 637,
height: 460,
left: 72,
bottom: 25,
right: 50
};
}
Insert cell
drawCw()
Insert cell
function labelForCountry(c, svgNode, spec) {
let countryData = data.filter(d => d[c.label]);
let endPoint = countryData.slice(-1)[0][c.label];
let endDay = countryData.slice(-1)[0].Tag;

d3.select(svgNode)
.select("#lines")
.append("text")
.style("font-family", "GTAmerica-Regular, GTAmericaRegular, GT America")
.attr("font-size", 14)
.attr("x", xScale(endDay, spec) + 6 + c.offsetX)
.attr("y", yScale(endPoint, spec) + 5 - c.offsetY)
.attr("fill", c.color)
.text(c.label);

d3.select(svgNode)
.select("#lines")
.append("circle")
.attr("cx", xScale(endDay, spec))
.attr("cy", yScale(endPoint, spec))
.attr("r", 4)
.attr("fill", c.color)
.text(c.label);
}
Insert cell
Insert cell
function dayLabels(svgNode, spec) {
console.log(spec);
let tage = data.filter(d => d.Tag % 30 == 0);
tage.forEach(tag => {
d3.select(svgNode)
.select("#dayLabels")
.append("text")
.attr("x", xScale(tag.Tag, spec) - 5)
.attr("y", spec.height)
.style("font-family", "GTAmerica-Regular, GTAmericaRegular, GT America")
.attr("font-size", 14)
.text(tag.Tag);
});
}
Insert cell
function yLabels(svgNode, spec) {
const format = d3.format(",.2f");
conf.labels.forEach(label => {
d3.select(svgNode)
.select("#yLabels")
.append("line")
.attr("x1", spec.left)
.attr("x2", spec.width)
.attr("y1", yScale(label, spec))
.attr("y2", yScale(label, spec))
.attr("stroke", "#000000")
.attr("stroke-width", 0.5);

d3.select(svgNode)
.select("#yLabels")
.append("text")
.attr("text-anchor", "end")
.attr("x", spec.left - 5)
.attr("y", yScale(label, spec) + 5)
.style("font-family", "GTAmerica-Regular, GTAmericaRegular, GT America")
.attr("font-size", 14)
.text(formatNumber(label));
});
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
getLabelXAxisAt = y => svg`<g>
<text transform="translate(50,${y})" style="font-family:GTAmerica-Regular, GTAmericaRegular, 'GT America'; font-size: 14px">Tage seit dem Auftreten des 100. Falls</text>
</g>`
Insert cell
import { formatNumber } from "@jonasoesch/nzz-utils"
Insert cell
function svgToCanvas(svg, scale = 1) {
return new Promise(resolve => {
const svgSize = svg.viewBox.baseVal;
const width = svgSize.width * scale;
const height = svgSize.height * scale;
const serializer = new XMLSerializer();
const svgString = serializer.serializeToString(svg);
const image = new Image();
image.src = `data:image/svg+xml;base64,${btoa(
unescape(encodeURIComponent(svgString))
)}`;

image.onload = () => {
const context = DOM.context2d(width, height, 1);
console.log(svg);
context.drawImage(
image,
0,
0,
svgSize.width * scale,
svgSize.height * scale
);
resolve(context.canvas);
};
});
}
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