makeChart5 = (dataset) => {
const w = 600;
const h = dataset.length * 24;
const chart5Svg = d3.create("svg")
.attr('width', w)
.attr('height', h);
const xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d.downloads)])
.range([80, w - 20]);
const yScale = d3.scaleLinear()
.domain([70, d3.max(dataset, (d) => d.thirty_day_keep)])
.range([h - 20, 20]);
const radiusScaleRetention = d3.scaleSqrt()
.domain([70, d3.max(dataset, (d) => d.thirty_day_keep)])
.range([2, 20]);
chart5Svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", (d) => xScale(d.downloads))
.attr("cy", (d) => yScale(d.thirty_day_keep))
.attr("r", (d) => radiusScaleRetention(d.thirty_day_keep))
.attr("fill", "steelblue")
.attr("opacity", 0.7);
chart5Svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.attr("x", (d) => xScale(d.downloads))
.attr("y", (d) => yScale(d.thirty_day_keep) - radiusScaleRetention(d.thirty_day_keep) + 20)
.text((d) => d.app_name)
.style("font-size", "8px")
.style("text-anchor", "middle")
.style("alignment-baseline", "middle");
chart5Svg.append("g")
.attr("class", "axis")
.attr("transform", `translate(0, ${h - 20})`)
.call(d3.axisBottom(xScale));
chart5Svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(80, 0)")
.call(d3.axisLeft(yScale).tickFormat(d => `${d}%`));
return chart5Svg.node();
}