如何在 d3 中悬停时增加饼图段的大小

Posted

技术标签:

【中文标题】如何在 d3 中悬停时增加饼图段的大小【英文标题】:How to increase size of pie segment on hover in d3 【发布时间】:2015-08-29 06:27:04 【问题描述】:

我使用 d3 创建了饼图。 如何在悬停时增加饼图的大小? 如您所见,绿色段太小了,所以我想像红色段一样改变它的大小。我该怎么做?

我的代码:

var w = 400;
var h = 400;
var r = h/2;
var color = d3.scale.category20c();

var data = ["label":"Category A", "value":20, 
                  "label":"Category B", "value":50, 
                  "label":"Category C", "value":30,
           "label":"Category A", "value":20, 
                  "label":"Category B", "value":50, 
                  "label":"Category C", "value":30,
           "label":"Category A", "value":20, 
                  "label":"Category B", "value":50, 
                  "label":"Category C", "value":5];


var vis = d3.select('#chart').append("svg:svg").data([data]).attr("width", w).attr("height", h).append("svg:g").attr("transform", "translate(" + r + "," + r + ")");
var pie = d3.layout.pie().value(function(d)return d.value;);

// declare an arc generator function
var arc = d3.svg.arc().outerRadius(r);
var arcOver = d3.svg.arc()
        .outerRadius(r + 9);

// select paths, use arc generator to draw
var arcs = vis.selectAll("g.slice").data(pie).enter().append("svg:g").attr("class", "slice");
arcs.append("svg:path")
    .attr("fill", function(d, i)
        return color(i);
    )
    .attr("d", function (d) 
        // log the result of the arc generator to show how cool it is :)
        console.log(arc(d));
        return arc(d);
    )
     .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");
        );;

js fiddle中有一个例子:jsfiddle 谢谢。

【问题讨论】:

【参考方案1】:

现在这是正确的代码。试试看..好的

<!DOCTYPE html>
<html>

<head>
  <title>Dsnap - Charts</title>
</head>

<body>
  <div id="wrapper">

  </div>
  <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
  <script>
    var canvas = d3.select('#wrapper')
      .append('svg')
      .attr(
        'width': 650,
        'height': 500
      );

    var data = [
      "label": "one",
      "value": 40
    , 
      "label": "two",
      "value": 30
    , 
      "label": "three",
      "value": 30
    ];

    var colors = ['red', 'blue'];

    var colorscale = d3.scale.linear().domain([0, data.length]).range(colors);

    var arc = d3.svg.arc()
      .innerRadius(0)
      .outerRadius(100);

    var arcOver = d3.svg.arc()
      .innerRadius(0)
      .outerRadius(150 + 10);

    var pie = d3.layout.pie()
      .value(function(d) 
        return d.value;
      );


    var renderarcs = canvas.append('g')
      .attr('transform', 'translate(440,200)')
      .selectAll('.arc')
      .data(pie(data))
      .enter()
      .append('g')
      .attr('class', "arc");

    renderarcs.append('path')
      .attr('d', arc)
      .attr('fill', function(d, i) 
        return colorscale(i);
      )
      .on("mouseover", function(d) 
        d3.select(this).transition()
          .duration(1000)
          .attr("d", arcOver);
      )
      .on("mouseout", function(d) 
        d3.select(this).transition()
          .duration(1000)
          .attr("d", arc);
      );

    renderarcs.append('text')
      .attr('transform', function(d) 
        var c = arc.centroid(d);
        console.log(c);
        return "translate(" + c[0] + "," + c[1] + ")";
      )
      .text(function(d) 
        return d.value + "%";
      );
  </script>
</body>

</html>

【讨论】:

感谢您的回答。您在点击时更改数据,但我不需要更改它。我想在不更改数据的情况下增加细分。 如果您能解释“这是正确的代码”之外的内容,那就太好了——您更改了什么以及为什么更改?代码是如何实现功能的? @LarsKotthoff,我检查了这段代码,但它不起作用。【参考方案2】:

我刚刚找到了解决问题的方法。

我在 d3 中更改了 startAngleendAngle

.on("mouseenter", function(d) 

         var endAngle = d.endAngle + 0.2;
         var startAngle = d.startAngle - 0.2;

              var arcOver = d3.svg.arc()
    .outerRadius(r + 9).endAngle(endAngle).startAngle(startAngle);

        d3.select(this)
           .attr("stroke","white")
           .transition()
           .duration(1000)
           .attr("d", arcOver)             
           .attr("stroke-width",6);
    )

工作示例:jsfiddle

【讨论】:

以上是关于如何在 d3 中悬停时增加饼图段的大小的主要内容,如果未能解决你的问题,请参考以下文章

如何用刻度包裹 D3 标签

发生鼠标悬停事件时如何更改饼图的颜色

d3.js 在鼠标悬停时更改折线图点的颜色和大小

如何更改D3中饼图的位置?

如何在d3.js中修复饼图标签

在 Force 有向图中将文本标签添加到 d3 节点并在悬停时调整大小