<svg id="topicsBubblechart"></svg>

<script>

    var topicsData = [
    <#list condenseTopicInformation as topicTuple>
        { topic: "${topicTuple.topic}", score: "${topicTuple.score?string?replace(',', '.')}"} <#sep>,
    </#list>
    ];

    const topics_bc_width = 1000;
    const topics_bc_height = 800;

    fillOpacity = 0.5;

    var svg = d3.select("#topicsBubblechart")
        .attr("width", topics_bc_width)
        .attr("height", topics_bc_height)

    var topics_bc_color = d3.scaleOrdinal(d3.schemeCategory10);
    var topics_bc_size = d3.scaleLinear().domain([1, 10]).range([30, 100]);

    var bubbles = svg.selectAll("circle")
            .data(topicsData)
            .enter().append("circle")
            .attr("r", d => topics_bc_size(d.score))
            .attr("fill", d => topics_bc_color(d.topic))
            .attr("fill-opacity", fillOpacity);

    var topics_labels = svg.selectAll("text")
            .data(topicsData)
            .enter().append("text")
            .attr("text-anchor", "middle")
            .attr("font-size", d => (10 * d.score) + "px")
            .attr("fill", "#000")
            .text(d => d.topic);

    var topics_bc_simulation = d3.forceSimulation(topicsData)
            .force("charge", d3.forceManyBody().strength(5))
            .force("center", d3.forceCenter(topics_bc_width / 2, topics_bc_height / 2))
            .force("collision", d3.forceCollide(d => topics_bc_size(d.score) + 25))
            .force("x", d3.forceX(topics_bc_width / 2).strength(0.1))
            .force("y", d3.forceY(topics_bc_height / 2).strength(0.1));

    topics_bc_simulation.on("tick", () => {
            bubbles.attr("cx", d => d.x).attr("cy", d => d.y);
            topics_labels.attr("x", d => d.x).attr("y", d => d.y);
        });

</script>
