Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3.js Pie chart .. can pie slice move when selected?

Just wondering is it possible to do something like this with d3?

http://jsfiddle.net/8T7Ew/

Where when you click on a certain pie slice the slice moves on click?

Have the pie created up to this point just wondering if I can add this feature

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  font: 10px sans-serif;
}

.arc path {
  stroke: #fff;
}

</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

var width = 960,
    height = 500,
    radius = Math.min(width, height) / 2;

var color = d3.scale.ordinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

var arc = d3.svg.arc()
    .outerRadius(radius - 10)
    .innerRadius(0);

var pie = d3.layout.pie()
    .sort(null)
    .value(function(d) { return d.population; });

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

d3.csv("data.csv", function(error, data) {

  data.forEach(function(d) {
    d.population = +d.population;
  });

  var g = svg.selectAll(".arc")
      .data(pie(data))
    .enter().append("g")
      .attr("class", "arc");

  g.append("path")
      .attr("d", arc)
      .style("fill", function(d) { return color(d.data.age); });

  g.append("text")
      .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
      .attr("dy", ".35em")
      .style("text-anchor", "middle")
      .text(function(d) { return d.data.age; });

});

</script>

Data is coming from a csv file.

Thanks

like image 803
bp2010 Avatar asked Oct 07 '14 10:10

bp2010


2 Answers

You can increase the arc radius of pie for highlighting. JSFiddle

var arcOver = d3.svg.arc()
    .outerRadius(r + 10);

g.append("path")
   .attr("d", arc)
   .style("fill", function(d) { return color(d.data.age); })
   .on("mouseenter", function(d) {
        d3.select(this)
           .attr("stroke","white")
           .transition()
           .duration(1000)
           .attr("d", arcOver)             
           .attr("stroke-width",6);
    })
    .on("mouseleave", function(d) {
        d3.select(this).transition()            
           .attr("d", arc)
           .attr("stroke","none");
    });
like image 62
Gilsha Avatar answered Sep 22 '22 19:09

Gilsha


I prefer changing Radius rather than stroke as it gives you smooth and nicer animation...

Using a function like this:

function pathEnter() {
  t = d3.select(this);
  t.transition()
  .attr('d', pathIn);
}

Run this code below to see the interaction:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  .arc text {
    font: 10px sans-serif;
    text-anchor: middle;
  }
  
  .arc path {
    stroke: #fff;
  }
</style>
<svg width="520" height="280"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
  var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    radius = Math.min(width, height) / 2 - 20,
    g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");


  var color = d3.scaleOrdinal(d3.schemeCategory10);

  var pie = d3.pie()
    .sort(null)
    .value(function(d) {
      return d.population;
    });

  var path = d3.arc()
    .outerRadius(radius)
    .innerRadius(0);

  var pathIn = d3.arc()
    .outerRadius(radius + 6)
    .innerRadius(0);


  function pathEnter() {
    t = d3.select(this);
    t.transition()
      .attr('d', pathIn);
  }

  function pathOut() {
    t = d3.select(this);
    t.transition()
      .attr('d', path);
  }

  var label = d3.arc()
    .outerRadius(radius - 40)
    .innerRadius(radius - 40);


  data = [{
      age: '<5',
      population: '2704659'
    },
    {
      age: '5-13',
      population: '4499890'
    },
    {
      age: '14-17',
      population: '2159981'
    },
    {
      age: '18-24',
      population: '3853788'
    },
    {
      age: '25-44',
      population: '14106543'
    },
    {
      age: '45-64',
      population: '8819342'
    },
    {
      age: '≥65',
      population: '612463'
    },
  ];

  data.population = +data.population;

  var arc = g.selectAll(".arc")
    .data(pie(data))
    .enter().append("g")
    .attr("class", "arc");


  arc.append("path")
    .attr("d", path)
    .on('mouseenter', pathEnter)
    .on('mouseout', pathOut)
    .attr("fill", function(d) {
      return color(d.data.age);
    });

  arc.append("text")
    .attr("transform", function(d) {
      return "translate(" + label.centroid(d) + ")";
    })
    .attr("dy", "0.35em")
    .text(function(d) {
      return d.data.age;
    });
</script>
like image 43
Alireza Avatar answered Sep 24 '22 19:09

Alireza