Yesha
Yesha

Reputation: 678

Force simulation of bubbles and texts going unbounded and inconsistent with XY axis

I have a d3 script given at this fiddle: https://jsfiddle.net/ngfoha56/8/

The problem that I am facing is, as number of bubbles having same or similar X-axis value are increasing, the bubbles are going beyond 100(wrt X-axis) and are even getting cut down from sides or are becoming unbounded. Like in the given example, G, H, I and J all have same X and Y values but appear at different positions wrt X and Y-Axis and 'I' is getting cut from sides. I want keep the bubbles consistent with X-axis and Y-axis and keep them bounded.

How do I do that?

I even tried doing

 circles.attr("cx", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); })
 .attr("cy", function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); });

as mentioned at this link: https://bl.ocks.org/mbostock/1129492

to keep the bubbles within the height and width mentioned but did not work.

Upvotes: 0

Views: 74

Answers (1)

Cyril Cherian
Cyril Cherian

Reputation: 32327

The problem is most of the pointsare close to 100 and so the center of the circle will be close to 100 thus the circle will lie out.

One way could be, give a threshold of 90% which means points outside 90% will be made 90% of thier value, so display wise it will show up at 90% of its current value, thus the pont will not appear to go out of the scale.

    var percent =0.90;//changeit as per your conveninece
    simulation = d3.forceSimulation()
    .force("x", d3.forceX(function(d) {
    var k = parseInt((xscale(+d.student_percentile)/width)*100);
    if (k > percent*100){//if less than percent
        return xscale(+d.student_percentile * percent)//reduce the percentile
    }
        return xscale(+d.student_percentile);
    }))
    .force("y", d3.forceY(function(d) {
    var k = parseInt((yscale(+d.rank)/height)*100);
    if (k > percent*100){
        return yscale(+d.rank * percent)
    }

        return yscale(+d.rank);
    }))
    .force("collide", d3.forceCollide(20)); 

working code here

Upvotes: 1

Related Questions