{
const data = {
Africa: 20.7,
Rest: 1479.3
};
const squareSize = 10;
const squaresPerRow = 50;
const gapSize = 2;
const totalSquares =
Math.floor(data["Africa"]) + Math.floor(data["Rest"]) + 1;
const colors = {
Africa: "#10827b",
Rest: "#dedede"
};
const container = d3.create("div");
container.html(`
<div style="font-family: Arial, sans-serif; font-size: 12px; margin-bottom: 10px;">
If each
<span style="display: inline-block; width: ${squareSize}px; height: ${squareSize}px; background-color: ${colors.Rest}; margin-right: 5px;"></span>
represents 1 million doses, this is how far
<span style="background-color: ${colors.Africa}; color: #fff">Africa’s</span> current production is from its target.
</div>
`);
const svg = container
.append("svg")
.attr("width", squaresPerRow * (squareSize + gapSize))
.attr(
"height",
Math.ceil(totalSquares / squaresPerRow) * (squareSize + gapSize)
);
const africaGroup = svg.append("g").attr("id", "africa");
const restGroup = svg.append("g").attr("id", "rest");
africaGroup
.selectAll("rect.africa")
.data(d3.range(Math.floor(data["Africa"])))
.enter()
.append("rect")
.attr("class", "africa")
.attr("width", squareSize)
.attr("height", squareSize)
.attr("x", (d) => (d % squaresPerRow) * (squareSize + gapSize))
.attr("y", (d) => Math.floor(d / squaresPerRow) * (squareSize + gapSize))
.attr("fill", colors["Africa"]);
const africaCount = Math.floor(data["Africa"]);
const partialSquareX = (africaCount % squaresPerRow) * (squareSize + gapSize);
const partialSquareY =
Math.floor(africaCount / squaresPerRow) * (squareSize + gapSize);
const africaRatio = data["Africa"] - africaCount;
const restRatio = 1 - africaRatio;
africaGroup
.append("rect")
.attr("x", partialSquareX)
.attr("y", partialSquareY)
.attr("width", squareSize)
.attr("height", squareSize * africaRatio)
.attr("fill", colors["Africa"]);
restGroup
.append("rect")
.attr("x", partialSquareX)
.attr("y", partialSquareY + squareSize * africaRatio)
.attr("width", squareSize)
.attr("height", squareSize * restRatio)
.attr("fill", colors["Rest"]);
restGroup
.selectAll("rect.rest")
.data(d3.range(Math.floor(data["Rest"])))
.enter()
.append("rect")
.attr("class", "rest")
.attr("width", squareSize)
.attr("height", squareSize)
.attr(
"x",
(d) => ((d + africaCount + 1) % squaresPerRow) * (squareSize + gapSize)
)
.attr(
"y",
(d) =>
Math.floor((d + africaCount + 1) / squaresPerRow) *
(squareSize + gapSize)
)
.attr("fill", colors["Rest"]);
return container.node();
}