为什么attrTween不起作用

时间:2017-01-04 14:20:38

标签: javascript d3.js

我试图模仿Mike Bostock Extending Arcs的一个例子。我的代码与迈克的代码非常相似,但是我的代码并不像他那样。

以下是JavaScript代码:

<!DOCTYPE html>
<html lang="en"> 
<head>
    <meta charset="utf-8">
    <title>Example</title>      
    <script src="static/d3.min.js"></script>
</head>
<body>
<script>
var Width = 500, Height = 400, innerRadius = 45, outerRadius = 100;
var colors = d3.scale.category10();

var svg = d3.select('body')
    .append('svg')
    .attr({ width: Width, height: Height });

var data = [40, 32, 35, 64, 83],
    pieData = d3.layout.pie()(data)

var ArcGen = d3.svg.arc()
    .innerRadius(innerRadius)
    .outerRadius(outerRadius)
    .padAngle(0.02)
    .startAngle(function(d){
        return d.startAngle;
    })
    .endAngle(function(d){
        return d.endAngle;
    });

var group = svg.append('g')
    .attr('transform', 'translate(' + [Width / 2.0, Height / 2.0] + ')');
var segment = group.selectAll('g')
    .data(pieData)
    .enter()
    .append('g');

segment
    .append('path')
    .attr('d', ArcGen)
    .attr('fill', function(d,i){ return colors(i); })
    .on('mouseover', arcTween(outerRadius * 1.2, 0))
    .on('mouseout', arcTween(outerRadius, 150));

function arcTween(oRadius, delay){
    // closure function
    return function(){
        d3.select(this)
            .transition()
            .delay(delay)
            .attrTween('d', function(d){
                var i = d3.interpolate(d.outerRadius, oRadius);
                return function(t){
                    d.outerRadius = i(t);
                    return ArcGen(d);
                }
            })
    };
};

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

这个例程很简单,没有错误也没有动作。

我有两个问题:

  • 如果需要在每个电弧发生器上链接startAngle和endAngle属性?我读了一些专业人士&#39;代码,例如Mike Bostock,在初始阶段不要添加这两个属性,并且在构造路径元素时它们的代码工作正常。
  • 我哪里错了?任何人都可以给我更多的例子。

谢谢大家!

1 个答案:

答案 0 :(得分:3)

您的代码有两个问题,您可以轻松地将其与Bostock的代码进行比较。

首先,这一行:

var i = d3.interpolate(d.outerRadius, oRadius);

在元素的基准中使用属性outerRadius。但它没有。您可以通过以下方式解决此问题:

.each(function(d) { d.outerRadius = outerRadius; })

其次,您的弧生成器正在设置外半径:

var ArcGen = d3.svg.arc()
    .innerRadius(innerRadius)
    .outerRadius(outerRadius)
    .padAngle(0.02)
    .startAngle(function(d) {
        return d.startAngle;
    })
    .endAngle(function(d) {
        return d.endAngle;
    });

删除它:

var ArcGen = d3.svg.arc()
    .innerRadius(innerRadius)
    .padAngle(0.02)
    .startAngle(function(d) {
        return d.startAngle;
    })
    .endAngle(function(d) {
        return d.endAngle;
    });

以下是您的工作代码,其中包含2项更改:

var Width = 500,
    Height = 400,
    innerRadius = 45,
    outerRadius = 100;
var colors = d3.scale.category10();

var svg = d3.select('body')
    .append('svg')
    .attr({
        width: Width,
        height: Height
    });

var data = [40, 32, 35, 64, 83],
    pieData = d3.layout.pie()(data)

var ArcGen = d3.svg.arc()
    .padAngle(0.02)
    .innerRadius(innerRadius)
    .startAngle(function(d) {
        return d.startAngle;
    })
    .endAngle(function(d) {
        return d.endAngle;
    });

var group = svg.append('g')
    .attr('transform', 'translate(' + [Width / 2.0, Height / 2.0] + ')');
var segment = group.selectAll('g')
    .data(pieData)
    .enter()
    .append('g');

segment
    .append('path')
    .each(function(d) {
        d.outerRadius = outerRadius;
    })
    .attr('d', ArcGen)
    .attr('fill', function(d, i) {
        return colors(i);
    })
    .on('mouseover', arcTween(outerRadius * 1.2, 0))
    .on('mouseout', arcTween(outerRadius, 150));

function arcTween(oRadius, delay) {
    // closure function
    return function() {
        d3.select(this)
            .transition()
            .delay(delay)
            .attrTween('d', function(d) {
                var i = d3.interpolate(d.outerRadius, oRadius);
                return function(t) {
                    d.outerRadius = i(t);
                    return ArcGen(d);
                }
            })
    };
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>