Jamie Hyland
Jamie Hyland

Reputation: 116

getting the centroid co-ordinates in d3

I'm trying to append a small circle to the centroid of the arcs in the pie chart I have made, the centroid returns an array of both and x and y co-ordinate value so I tried to separate it by using the array index [0],[1]

<!doctype HTML>
<html>
    <head>
        <title>Page Title</title>
        <meta charset="UTF-8">

        <script type="text/javascript" src="js/d3.min.js"></script>
        <link rel="stylesheet" type="text/css" href="css/style.css">

    </head>
    <body>

        <script type="text/javascript">

            //=================================================================================================================
            // initializing variables 


            var data = []; // empty array to hold the objects imported from the JSON file
            var oRadius = 300; //var holding value for the outer radius of the arc
            var iRadius = 80;  //var holding the value for the inner radius of the arc
            var cRadius = 3;   //var holding the value for the corner radius of the arc
            var colors = d3.scale.category20b();//built in D3 function to color pieces of data
            var width = 1400; //setting the width of the svg
            var height = 1000; //setting the height of the svg
            var dRadius = 5; //setting the radius for the dots
            var sColor = "white"; // color for the stroke of the arcs
            var dStrokeColor = "#666";
            var dFillColor  = "#ccc"
            var myChart;

            var myArcMaker= d3.svg.arc().outerRadius(oRadius).innerRadius(iRadius).cornerRadius(cRadius); //var that creates the arc
            var bigArcMaker=  d3.svg.arc().outerRadius(400).innerRadius(oRadius).cornerRadius(cRadius);

            var  mySvg =  d3.select('body')
                          .append('svg')
                          .attr('width', width)
                          .attr("height", height) //selecting the body and appending an, then svg setting the height and width properties for the svg
                          .append("g")
                          .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")// centers the pie chart in the center of the svg


            mySvg.append("g")
            .attr("class", "slices");
            mySvg.append("g")
           .attr("class", "dots");
            mySvg.append("g")
           .attr("class", "lines");



            var myPie =  d3.layout.pie()
                        .sort(null)
                        .startAngle(2*(Math.PI))
                        .endAngle(((Math.PI))/360)
                        .padAngle(-1.5*(2*(Math.PI))/360).value(function(d){return d.value}); //setting the values for that start angle, end angle and pad angle for the arcs and takes in the the values from the objects in the data array


            //===================================================================================================================

                 d3.json("data.json", function (json) // importing the json file
            {

                data = json; // setting the empty data array equal to the values of the objects in the json file
                visual(); // this function holds all the d3 code to create the arc

            })




            function visual() // this function prevents the code that creates the arc from running before the objects from the json file are added into the empty data array
            {

                console.log(data); // checking to see if the objects are loaded into the data ray using the console in chrome


                  var z = function(d) {return myArcMaker.centroid()}
                  var x1 = z[0]
                  var y1 = z[1]

                 console.log(x1);

                var slice =  mySvg.select(".slices")
                             .selectAll("path.slice")
                             .data(myPie(data)) // 
                             .enter()
                             .append("path")
                             .attr("class", "slice")
                             .attr("d", function(d)
                              {
                               return myArcMaker(d)
                              })
                             .attr("fill", function(d, i) {return colors(i);}) //using the d3 color brewer to color each arc
                             .attr("stroke", "white") //giving each arc a stroke of white

                                var dots = slice.select(".dots")
                                        .data(myPie(data))
                                        .enter()
                                        .append("circle")
                                        .attr("class", "dots")
                                        .attr("cx", x1)
                                        .attr("cy", y1)
                                        .attr("r", dRadius)
                                        .attr("fill", dFillColor)
                                        .attr("stroke", sColor)

                                }
        </script>
    </body>
</html>

When I run the code however the dots are only appearing in the center of the pie chart and arent appending to the x,y values of each respective arc. Any ideas on how to iterate through each arc to append the dot?

json data:

> [ {     "Fruits": "Oranges",   "value": 60 }, {     "Fruits":
> "Apples",   "value": 135 }, {     "Fruits": "Bananas",   "value": 225
> }, {     "Fruits": "Kiwis",   "value": 120 },   {     "Fruits":
> "Pears",   "value": 175 }, {     "Fruits": "Grapes",   "value": 145  }
> ]

Upvotes: 0

Views: 793

Answers (1)

Gilsha
Gilsha

Reputation: 14591

Set the dot positions as shown below.

 var dots = slice.select(".dots")
          .data(myPie(data))
          .enter()
          .append("circle")
          .attr("transform", function(d) {                  
               return "translate(" + myArcMaker.centroid(d) + ")";
           })
           .attr("r", dRadius)
           .attr("fill", dFillColor)
           .attr("stroke", sColor);

And you missed value settings from d3 pie.

var myPie = d3.layout.pie()
  .sort(null)
  .startAngle(2 * (Math.PI))
  .endAngle(((Math.PI)) / 360)
  .value(function(d) {
    return d.value;
  });

Working Fiddle:

var data = [{
  "Fruits": "Oranges",
  "value": 60
}, {
  "Fruits": "Apples",
  "value": 135
}, {
  "Fruits": "Bananas",
  "value": 225
}, {
  "Fruits": "Kiwis",
  "value": 120
}, {
  "Fruits": "Pears",
  "value": 175
}, {
  "Fruits": "Grapes",
  "value": 145
}];

var oRadius = 300; //var holding value for the outer radius of the arc
var iRadius = 80; //var holding the value for the inner radius of the arc
var cRadius = 3; //var holding the value for the corner radius of the arc
var colors = d3.scale.category20b(); //built in D3 function to color pieces of data
var width = 1400; //setting the width of the svg
var height = 1000; //setting the height of the svg
var dRadius = 5; //setting the radius for the dots
var sColor = "white"; // color for the stroke of the arcs
var dStrokeColor = "#666";
var dFillColor = "#ccc"
var myChart;

var myArcMaker = d3.svg.arc().outerRadius(oRadius).innerRadius(iRadius);
var bigArcMaker = d3.svg.arc().outerRadius(200).innerRadius(oRadius);

var mySvg = d3.select('body')
  .append('svg')
  .attr('width', width)
  .attr("height", height) 
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");


mySvg.append("g")
  .attr("class", "slices");

mySvg.append("g")
  .attr("class", "dots");

mySvg.append("g")
  .attr("class", "lines");



var myPie = d3.layout.pie()
  .sort(null)
  .startAngle(2 * (Math.PI))
  .endAngle(((Math.PI)) / 360)
  .value(function(d) {
    return d.value;
  });


visual();


function visual() {
       var slice = mySvg.select(".slices")
      .selectAll("path.slice")
      .data(myPie(data)) // 
      .enter()
      .append("path")
      .attr("class", "slice")
      .attr("d", function(d) {
        return myArcMaker(d)
      })
      .attr("fill", function(d, i) {
        return colors(i);
      }) //using the d3 color brewer to color each arc
      .attr("stroke", "white") //giving each arc a stroke of white

    var dots = slice.select(".dots")
      .data(myPie(data))
      .enter()
      .append("circle")
      .attr("class", "dots")
      .attr("transform", function(d) {
        return "translate(" + myArcMaker.centroid(d) + ")";
      })

    .attr("r", dRadius)
      .attr("fill", dFillColor)
      .attr("stroke", sColor)

  }
body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  width: 960px;
  height: 500px;
  position: relative;
}
svg {
  width: 100%;
  height: 100%;
}
path {
  stroke-width: 2px;
}
polyline {
  opacity: .3;
  stroke: black;
  stroke-width: 2px;
  fill: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Upvotes: 1

Related Questions