【问题标题】:D3.js Pie chart .. can pie slice move when selected?D3.js 饼图 .. 选择时饼片可以移动吗?
【发布时间】:2014-12-01 18:47:29
【问题描述】:

只是想知道用 d3 可以做这样的事情吗?

http://jsfiddle.net/8T7Ew/

当您单击某个饼图切片时,切片会在单击时移动到哪里?

到目前为止,我已经创建了馅饼,只是想知道我是否可以添加此功能

<!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>

数据来自 csv 文件。

谢谢

【问题讨论】:

    标签: javascript d3.js charts pie-chart


    【解决方案1】:

    您可以增加饼图的圆弧半径以进行高亮显示。 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");
        });
    

    【讨论】:

    【解决方案2】:

    我更喜欢改变 半径 而不是描边,因为它可以为您提供流畅和更好的动画...

    使用这样的函数:

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

    运行下面的代码来查看交互:

    <!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>

    【讨论】:

      【解决方案3】:

      使用属性 transform="translate(x, y)" 将实际移动每个饼图。

      http://jsfiddle.net/qkHK6/3306/

      以@Gilsha 的回答为基础(我知道这个问题已经过时,但我想我会将这个回答存档以供存档)...

      g.append("path")
          .attr("d", arc)
          .attr("opacity", "1.0")
          .on("mouseenter", function (d) {
              var arcOver = d3.arc()
                  .outerRadius(radius).innerRadius(0).startAngle(d.startAngle + 0.01).endAngle(d.endAngle - 0.01);
              var transformText = getTranslate(d.startAngle + 0.01, d.endAngle - 0.01, 20);
      
              d3.select(this)
                  .attr("d", arcOver)
                  .transition()
                  .duration(200).ease(d3.easeBack)
                  .attr("transform", transformText)
                  .attr("style", "fill: rgb(102, 102, 102)");
          })
          .on("mouseleave", function (d) {
              d3.select(this)
                  .attr("d", arc)
                  .transition().ease(d3.easeBack)
                  .duration(600)
                  .attr("transform", "translate(0,0)")
                  .attr("style", "fill: " + color(d.data));
          })
          .style("fill", function (d) { return color(d.data); });
      

      另外 d3.arc() 来自版本 4。

      下面的辅助方法:

      getTranslate = function (startAngle, endAngle, distance) {
          var xTranslate, yTranslate;
          var startQ = getQuadrant(startAngle);
          var endQ = getQuadrant(endAngle);
      
      //Assume there are 7 possibilities since last slice always ends at Tau or 12 o'clock when doing a d.endAngle
          switch (true) {
              case (startQ == 1 && endQ == 1):
                  xTranslate = distance * 0.5;
                  yTranslate = distance * -1.5;
                  break;
              case (startQ == 1 && endQ == 4):
                  xTranslate = distance * 1.5;
                  yTranslate = distance * 0.5;
                  break;
              case (startQ == 4 && endQ == 4):
                  xTranslate = distance * 0.5;
                  yTranslate = distance * 1.5;
                  break;
              case (startQ == 4 && endQ == 3):
                  xTranslate = distance * -0.5;
                  yTranslate = distance * 1.5;
                  break;
              case (startQ == 3 && endQ == 3):
                  xTranslate = distance * -1.5;
                  yTranslate = distance * 0.5;
                  break;
              case (startQ == 3 && endQ == 2):
                  xTranslate = distance * -1.5;
                  yTranslate = distance * -0.5;
                  break;
              case (startQ == 2 && endQ == 2):
                  xTranslate = distance * -0.5;
                  yTranslate = distance * -1.5;
                  break;
          }
      
          return "translate(" + xTranslate + "," + yTranslate + ")";
      }
      
      getQuadrant = function (angle) {
          switch (true) {
              case angle < (Math.PI * 0.5):
                  return 1;
                  break;
              case angle >= (Math.PI * 1.5):
                  return 2;
                  break;
              case ((Math.PI < angle) && angle <= (Math.PI * 1.5)):
                  return 3;
                  break;
              default:
                  return 4;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-10
        • 1970-01-01
        • 1970-01-01
        • 2014-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多