soum
soum

Reputation: 1159

how to avoid overlap of shapes when using d3.js

I am drawing circles by setting a fixed x position but a changing y position. The problem is the circles are overlapping since the radius of each circle is different.

Ideally in theory to solve that I would probably want to get the y position of the previous circle and add the radius of the current circle to it to get the y position of the current circle. Correct me if I am thinking it wrong.

Right now I am doing something like this now

var k = 10;

var circleAttributes = circles.attr("cx", '150')
        .attr("cy", function (d) {
        return (k++) * 10;    //this is a very gray area
    })

And I am getting an overlap. Ideally I would like to space the circles form each other. Even if the outer edges touch each other I could live with that. How should I approach it?

I am writing a range which i am using to get the radius

var rScale = d3.scale.linear()
        .domain([min, max])
        .range([10, 150]);

and simply passing that as the radius like this

.attr("r", function(d) { return rScale(d.consumption_gj_);})

This is my fiddle

http://jsfiddle.net/sghoush1/Vn7mf/27/

Upvotes: 3

Views: 4509

Answers (2)

elsherbini
elsherbini

Reputation: 1616

Did a solution here: http://tributary.io/inlet/6283630

The key was to keep track of the sum of the radius of all previous circles. I did that in a forEach loop:

data.forEach(function(d,i){
  d.radius = rScale(d.consumption_gj_);
  if (i !== 0){
    d.ypos = d.radius*2 + data[i-1].ypos;
  }
  else {
    d.ypos = d.radius*2;
  }
})

then, when setting the attributes of the circles you can use your new d.radius and d.ypos

    var circleAttributes = circles.attr("cx", '150')
        .attr("cy", function (d,i) {
            return d.ypos + 5*i;
    })
        .attr("r", function(d) { return d.radius;}) 

Upvotes: 2

BentOnCoding
BentOnCoding

Reputation: 28158

The Charge Property

The charge in a force layout refers to how nodes in the environment push away from one another or attract one another. Kind of like magnets, nodes have a charge that can be positive (attraction force) or negative (repelling force).

From the Documentation:

If charge is specified, sets the charge strength to the specified value. If charge is not specified, returns the current charge strength, which defaults to -30. If charge is a constant, then all nodes have the same charge. Otherwise, if charge is a function, then the function is evaluated for each node (in order), being passed the node and its index, with the this context as the force layout; the function's return value is then used to set each node's charge. The function is evaluated whenever the layout starts.

A negative value results in node repulsion, while a positive value results in node attraction. For graph layout, negative values should be used; for n-body simulation, positive values can be used. All nodes are assumed to be infinitesimal points with equal charge and mass. Charge forces are implemented efficiently via the Barnes–Hut algorithm, computing a quadtree for each tick. Setting the charge force to zero disables computation of the quadtree, which can noticeably improve performance if you do not need n-body forces.

A good tutorial that will help you see this in action:

http://vallandingham.me/bubble_charts_in_d3.html

Upvotes: 2

Related Questions