Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Placing dots in an arc

I have an arc and currently the dots that belong to that arc use d3.layout.pack() to place them, this however only places the dots in the arc in a circle obviously.

Is there a way that I could place the dots in an arc to use the whole space of an arc (currently it just clusters the points in the center of the arc in a circle)

I tried messing with the padding but obviously its not what i needed as it can push the dots out of the bounds of an arc

Thanks Mark

EDIT - Code The code is just standard layout pack code. I am trying to see if there is a way i can "pack" the dots in an arc.

var pack = d3.layout.pack()
.sort(null)
.size([_config.RingWidth, _config.RingWidth])//config.RingWidth is the width of the arc
.value(function (d) {
  return 1 * Math.random();//the dots are all the same size
});

The dots are then processed and the pack is used

dots2 = new Array();
for (var clusterNum = 0; clusterNum < _hierarchy.Dots.dotsArray.length; clusterNum++) {
    dots2[clusterNum] = svg.selectAll(".node" + clusterNum)
      .data(pack.nodes(_hierarchy.Dots.dotsArray[clusterNum])
      .filter(function (d) {
         return !d.children;
}));

Current

Wanted

The top image is how it currently functions and the bottom is how I want it to function. As you can see in large arcs it looks strange that it cannot use all the arc, but i am lost on how I could achieve this (i tried padding the pack but then it goes outside the boundaries of the arc).

Cheers

like image 392
markblue777 Avatar asked Aug 18 '14 10:08

markblue777


1 Answers

One way you can achieve it is by linearly transforming the 1x1 square in which d3.layout.pack draws the bubbles by default, as shown here:

Transformation of the coordinate system to map a square to an arc segment

The key functions which do that are these:

// Does the transformation from [(0,0), (0,1), (1,1), (1,0)] sqaure to an arc
// with the parameters [ (r0, theta0), (r0, theta1), (r1, theta1), (r1, theta0) ]
function transform_x(xy, r0, r1, theta0, theta1) {
    var x = xy.x, y = xy.y;
    return ((1 - x) * r0 + x * r1) * Math.sin((1 - y) * theta0 + y * theta1);
}

function transform_y(xy, r0, r1, theta0, theta1) {
    var x = xy.x, y = xy.y;
    return ((1 - x) * r0 + x * r1) * Math.cos((1 - y) * theta0 + y * theta1);
}

A working demo of the code is here: http://jsfiddle.net/tq4rjs7v/

like image 193
musically_ut Avatar answered Sep 19 '22 22:09

musically_ut