wordCloud = (data, word, frequency, maxSize, type) => {
if (type === undefined) {
data.map(d => (d.type = 0));
}
const height = 300;
const margin = {
t: 0,
l: 30,
r: 20,
b: 0
};
const padding = 2;
let x = d3
.scalePoint()
.domain(timeFrames)
.range([margin.l, width - margin.l - margin.r]);
let svg = d3
.select(html`<svg></svg>`)
.attr('width', width)
.attr('height', height);
const colors = d3.schemeSet1.slice(0, new Set(data.map(d => d[type])).size);
const luminance = 50;
const textColor = d3
.scaleQuantile()
.range(["#fff", "#000"])
.domain([0, luminance, 100]);
const r = d3
.scaleSqrt()
.domain([0, d3.max(data, d => d[frequency])])
.range([0, maxSize]);
const simulation = d3
.forceSimulation(data)
.force("x", d3.forceX(d => x(d[type])).strength(1))
.force("y", d3.forceY(height / 2).strength(0.2))
.force(
"collide",
d3
.forceCollide()
.radius(d => r(d[frequency]) + padding)
.iterations(10)
)
.alpha(0.2);
let gBubble = svg.selectAll('gBubble').data(data);
gBubble.exit().remove();
let bubble = gBubble
.enter()
.append('g')
.classed('gBubble', true)
.attr('id', d => d[word]);
bubble
.append('circle')
.attr('r', d => r(d[frequency]))
.attr('fill', d => d[word])
.attr('fill-opacity', 0.4)
.attr('stroke', d => d[word])
.attr('stroke-width', 1);
gBubble = gBubble.merge(bubble);
gBubble.call(drag(simulation));
simulation.nodes(data).on('tick', () => {
gBubble.attr('transform', d => 'translate(' + d.x + ',' + d.y + ')');
});
const xaxis = svg
.append("g")
.attr("transform", `translate(0,${height - 50})`)
.call(d3.axisBottom(x));
return Object.assign(svg.node());
}