chart = {
const marginTop = 20;
const marginRight = 1;
const marginBottom = 40;
const marginLeft = 40;
const rowHeight = 16;
const width = 928;
const height = rowHeight * data.names.length + marginTop + marginBottom;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("viewBox", [0, 0, width, height])
.attr("width", width)
.attr("height", height)
.attr("style", "max-width: 100%; height: auto;");
const x = d3.scaleLinear()
.domain([d3.min(data.years), d3.max(data.years) + 1])
.rangeRound([marginLeft, width - marginRight])
const y = d3.scaleBand()
.domain(data.names)
.rangeRound([marginTop, height - marginBottom])
const color = d3.scaleSequentialSqrt([0, d3.max(data.values, d => d3.max(d))], d3.interpolatePuRd);
svg.append("g")
.call(g => g.append("g")
.attr("transform", `translate(0,${marginTop})`)
.call(d3.axisTop(x).ticks(null, "d"))
.call(g => g.select(".domain").remove()))
.call(g => g.append("g")
.attr("transform", `translate(0,${height - marginBottom + 4})`)
.call(d3.axisBottom(x)
.tickValues([data.year])
.tickFormat(x => x)
.tickSize(marginTop + marginBottom - height - 10))
.call(g => g.select(".tick text")
.clone()
.attr("dy", "2em")
.style("font-weight", "bold")
.text("Measles vaccine introduced"))
.call(g => g.select(".domain").remove()));
svg.append("g")
.attr("transform", `translate(${marginLeft},0)`)
.call(d3.axisLeft(y).tickSize(0))
.call(g => g.select(".domain").remove());
const f = d3.format(",d");
const format = d => isNaN(d) ? "N/A cases"
: d === 0 ? "0 cases"
: d < 1 ? "<1 case"
: d < 1.5 ? "1 case"
: `${f(d)} cases`;
svg.append("g")
.selectAll("g")
.data(data.values)
.join("g")
.attr("transform", (d, i) => `translate(0,${y(data.names[i])})`)
.selectAll("rect")
.data(d => d)
.join("rect")
.attr("x", (d, i) => x(data.years[i]) + 1)
.attr("width", (d, i) => x(data.years[i] + 1) - x(data.years[i]) - 1)
.attr("height", y.bandwidth() - 1)
.attr("fill", d => isNaN(d) ? "#eee" : d === 0 ? "#fff" : color(d))
.append("title")
.text((d, i) => `${format(d)} per 100,000 people in ${data.years[i]}`);
return Object.assign(svg.node(), {scales: {color}});
}