Having trouble getting bubbles to cluster together in center of doughnut chart

45 Views Asked by At

Current look:

visual_look

What I'm after:

Inspiration_of_what_I_want_it_to_look_like

Visual Issue:

I have been trying to create a doughnut chart with clustered bubbles. The goal is to have all the bubbles grouped closely together in the center of the doughnut chart. However, the current implementation does not produce the expected result.

What I've Tried:

I have attempted to cluster the bubbles by calculating their positions relative to the center of the chart. I've used polar coordinates to determine their locations, but the bubbles still do not cluster as desired.

Desired Outcome:

I want all the bubbles to be tightly clustered together at the center of the doughnut chart, creating a visually appealing and coherent representation of the data.

Request for Assistance:

I'm seeking guidance on how to modify my code to achieve the desired clustering effect. Are there any adjustments or approaches that I should consider to make the bubbles cluster together effectively in the center of the doughnut chart?

class BubbleChart {
    constructor(canvasId, data) {
        this.canvasId = canvasId;
        this.data = data;
        this.initVis();
    }

    initVis() {
        let vis = this; // Define 'vis' as a reference to the class instance

        // Initialize chart dimensions and other settings using 'vis'
        vis.margin = { top: 100, right: 50, bottom: 50, left: 110 };
        vis.width = 400 - vis.margin.left - vis.margin.right;  // Width of the bubble chart canvas
        vis.height = 400 - vis.margin.top - vis.margin.bottom; // Height of the bubble chart canvas

        vis.createChart();
    }

    createChart() {
        let vis = this; // Reference to the class instance

        const canvas = document.getElementById(vis.canvasId);
        const ctx = canvas.getContext('2d');

        // Define the number of bubbles
        const numBubbles = vis.data.length;
        const clusterRadius = Math.min(vis.width, vis.height) * 0.3; // Radius of the cluster

        // Calculate the positions of bubbles closely together in the center
        const clusterX = vis.width / 2; // Cluster center X
        const clusterY = vis.height / 2; // Cluster center Y
        const angleIncrement = (2 * Math.PI) / numBubbles; // Angle increment for placing bubbles

        const bubbleData = {
            datasets: [{
                label: vis.data.map(d => d.Topic),
                backgroundColor: vis.data.map((_, i) => vis.getColor(i)),
                data: vis.data.map((item, i) => {
                    // Calculate positions closely together in the center
                    const bubbleAngle = i * angleIncrement; // Angle for the current bubble within the cluster
                    const bubbleX = clusterX + clusterRadius * Math.cos(bubbleAngle); // Adjusted X within cluster
                    const bubbleY = clusterY + clusterRadius * Math.sin(bubbleAngle); // Adjusted Y within cluster
                    const r = 10; // Use a fixed radius for all bubbles within the cluster
                    return {
                        x: bubbleX,
                        y: bubbleY,
                        r: r
                    };
                })
            }]
        };

        new Chart(ctx, {
            type: 'bubble',
            data: bubbleData,
            options: {
                plugins: {
                    legend: {
                        display: false // This will hide the legend
                    }
                },
                scales: {
                    x: { display: false },
                    y: { display: false }
                },
                tooltips: { // Ensure tooltips are enabled for hover information
                    enabled: true
                },
                maintainAspectRatio: false
            }
        });
    }

    getColor(index) {
        const colors = ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF', '#FF9F40'];
        return colors[index % colors.length];
    }
}
0

There are 0 best solutions below