The Old County
The Old County

Reputation: 109

d3 connected series circles

I am trying to create an application where the circles touch the edges of each other.

I am having issues trying to calculate the cx function.

.attr("cx", function(d, i) {
  return (i * 50) + 50; //Math.sqrt(d) ;// + 50; 
})

enter image description here

http://jsfiddle.net/59bunh8u/56/

  var el = $('.serieschart');
  var w = el.data("width");
  var h = el.data("height");


  var margin = {
    top: 65,
    right: 90,
    bottom: 5,
    left: 150
  };

  var svg = d3.select(el[0]).append("svg")
    .attr("class", "series")
    .attr("width", w + margin.left + margin.right)
    .attr("height", h + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  svg.selectAll("circle")
    .data([400, 100, 1000, 300])
    .enter().append("circle")
    .attr("cy", 60)
    .attr("cx", function(d, i) {
      return (i * 50) + 50; //Math.sqrt(d) ;// + 50; 
    })
    .attr("fill", function(d, i) {
      return "#00ccff";
    })
    .attr("r", function(d) {
      return Math.sqrt(d);
    });

Upvotes: 0

Views: 262

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102218

Here I'm using a "counter" to add the values...

var counter = 0;

... and assigning the data to a variable...

var data = [400, 100, 1000, 300];

... for better accessing different indices.

Then, for each circle element, we set the cx attribute:

.attr("cx", function(d, i) {
    return i ? (counter += Math.sqrt(data[i - 1]) + Math.sqrt(data[i])) : counter;
})

I put the ternary operator because, of course, there is no data[i - 1] for the first circle. Thus, this is the mathematical explanation:

  • For the first circle: return counter (or i), which is zero.
  • From the second circle on: add both this circle's radius (Math.sqrt(data[i])) and the last circle's radius (Math.sqrt(data[i - 1])) to counter, and return counter.

Here is the demo:

$(document).ready(function() {


  var rawData = [{
    "name": "Twitter",
    "items": [{
        "label": "15 billion",
        "unit": "per day",
        "value": 5500
      }
      /*,
      				{
      					"label" : "450 checkins",
      					"unit" : "per day",
      					"value" : 400
      				}*/
    ]
  }, {
    "name": "Facebook",
    "items": [{
        "label": "5 billion",
        "unit": "per day",
        "value": 3000
      }
      /*,
      				{
      					"label" : "2000 checkins",
      					"unit" : "per day",
      					"value" : 1500
      				}*/
    ]
  }, {
    "name": "Ebay",
    "items": [{
        "label": "7 billion",
        "unit": "per day",
        "value": 300
      }
      /*,
      				{
      					"label" : "300 checkins",
      					"unit" : "per day",
      					"value" : 500
      				}*/
    ]
  }];


  var el = $('.serieschart');
  var w = el.data("width");
  var h = el.data("height");


  var margin = {
    top: 65,
    right: 90,
    bottom: 5,
    left: 150
  };

  var counter = 0;

  var svg = d3.select(el[0]).append("svg")
    .attr("class", "series")
    .attr("width", w + margin.left + margin.right)
    .attr("height", h + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  var data = [400, 100, 1000, 300];

  svg.selectAll("circle")
    .data(data)
    .enter().append("circle")
    .attr("cy", 60)
    .attr("stroke", "black")
    .attr("cx", function(d, i) {
      return i ? (counter += Math.sqrt(data[i - 1]) + Math.sqrt(data[i])) : counter;
    })
    .attr("fill", function(d, i) {
      return "#00ccff";
    })
    .attr("r", function(d) {
      return Math.sqrt(d);
    });




});
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<div id="holder">
  <div class="serieschart" data-role="serieschart" data-width=450 data-height=180></div>
</div>

Upvotes: 3

Related Questions