chart_force = {
replay;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, chart_param.width, chart_param.height]);
const nodes1 = nodes.map(d => Object.create(d));
const g = svg.append("g").attr("class", ".node");
svg.append("g")
.attr("class", "legend legend--ordinal")
.attr("transform", "translate(20,40)")
.attr("font-size", "10px");
svg.append("text").attr("x", 10).attr("y", 20).text("Top 10 AirBNB Earners in Boston, " + time).style("font-size", "15px").attr("alignment-baseline","middle")
svg.select(".legend")
.call(legend);
const tooltip = d3
.select('body')
.append('div')
.attr('class', 'd3-tooltip')
.style('position', 'absolute')
.style('z-index', '10')
.style('visibility', 'hidden')
.style('padding', '10px')
.style('background', 'rgba(0,0,0,0.6)')
.style('border-radius', '4px')
.style('color', '#fff')
.text('a simple tooltip');
const sim = d3.forceSimulation(nodes1)
.force("x", d3.forceX(x(0.5)).strength(.2))
.force("y", d3.forceY(y(0.5)).strength(.2))
.force('charge', d3.forceManyBody().strength(-10).distanceMax(1000))
.force("collide", d3.forceCollide().radius(d => d.r + 2));
const node = g.selectAll(".node")
.data(nodes1).enter()
.append("circle")
.classed("node", true)
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("fill", d => color(d.group))
.on('mouseover', function (event,d, i) {
tooltip
.html(`
<div style='float: right'>
Host Name: ${d.host_name} <br/>
Listings: ${d.listings_count} <br/>
Monthly Revenue: ${d3.format("$,.6r")(d.revenue)}
</div>`)
.style('visibility', 'visible');
})
.on('mousemove', function (event) {
tooltip
.style('top', event.pageY - 10 + 'px')
.style('left', event.pageX + 10 + 'px');
})
.on('mouseout', function (event) {
tooltip.html(``).style('visibility', 'hidden');
});
node.transition()
.delay((d, i) => Math.random() * 500)
.duration(750)
.attrTween("r", d => {
const i = d3.interpolate(0, d.r);
return t => d.r = i(t);
});
sim.on("tick", () => {
node
.attr("cx", d => d.x)
.attr("cy", d => d.y);
});
svg.call(d3.zoom()
.extent([[0, 0], [chart_param.width * 2, chart_param.height * 2]])
.scaleExtent([-100, 100])
.on("zoom", zoomed));
function zoomed({transform}) {
g.attr("transform", transform);
}
return svg.node()
}