【问题标题】:d3-transition attrTween, styleTween methods are not getting triggered in d3 version 4d3-transition attrTween、styleTween 方法在 d3 版本 4 中未触发
【发布时间】:2017-02-22 09:55:04
【问题描述】:

我正在尝试将以下圆环图从 d3.js v3 升级到 d3.js v4。

http://bl.ocks.org/dbuezas/9306799

我已经用新版本中的等效方法替换了所有旧版本的方法名称。

d3.scale.ordinal() 到 d3.scaleOrdinal()

d3.layout.pie() 到 d3.pie()

d3.svg.arc() 到 d3.arc()

路径标签的"d"属性未生成。

并且方法“attrTween 和 styleTween”在 v4 中甚至都没有被触发。

我为此创建了一个plunker。

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

body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  width: 960px;
  height: 500px;
  position: relative;
}

svg {
    width: 100%;
    height: 100%;
}

path.slice{
    stroke-width:2px;
}

polyline{
    opacity: .3;
    stroke: black;
    stroke-width: 2px;
    fill: none;
}

</style>
<body>
<button class="randomize">randomize</button>

<script src="http://d3js.org/d3.v4.min.js"></script>
<script>

var svg = d3.select("body")
    .append("svg")
    .append("g")

svg.append("g")
    .attr("class", "slices");
svg.append("g")
    .attr("class", "labels");
svg.append("g")
    .attr("class", "lines");

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

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

var arc = d3.arc()
    .outerRadius(radius * 0.8)
    .innerRadius(radius * 0.4);

var outerArc = d3.arc()
    .innerRadius(radius * 0.9)
    .outerRadius(radius * 0.9);

svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var key = function(d){ return d.data.label; };

var color = d3.scaleOrdinal()
    .domain(["Lorem ipsum", "dolor sit", "amet", "consectetur", "adipisicing", "elit", "sed", "do", "eiusmod", "tempor", "incididunt"])
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

function randomData (){
    var labels = color.domain();
    return labels.map(function(label){
        return { label: label, value: Math.random() }
    });
}

change(randomData());

d3.select(".randomize")
    .on("click", function(){
        change(randomData());
    });


function change(data) {

    /* ------- PIE SLICES -------*/
    var slice = svg.select(".slices").selectAll("path.slice")
        .data(pie(data), key);

    slice.enter()
        .insert("path")
        .style("fill", function(d) { return color(d.data.label); })
        .attr("class", "slice");

    slice       
        .transition().duration(1000)
        .attrTween("d", function(d) {
            this._current = this._current || d;
            var interpolate = d3.interpolate(this._current, d);
            this._current = interpolate(0);
            return function(t) {
                return arc(interpolate(t));
            };
        })

    slice.exit()
        .remove();

    /* ------- TEXT LABELS -------*/

    var text = svg.select(".labels").selectAll("text")
        .data(pie(data), key);

    text.enter()
        .append("text")
        .attr("dy", ".35em")
        .text(function(d) {
            return d.data.label;
        });

    function midAngle(d){
        return d.startAngle + (d.endAngle - d.startAngle)/2;
    }

    text.transition().duration(1000)
        .attrTween("transform", function(d) {
            this._current = this._current || d;
            var interpolate = d3.interpolate(this._current, d);
            this._current = interpolate(0);
            return function(t) {
                var d2 = interpolate(t);
                var pos = outerArc.centroid(d2);
                pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
                return "translate("+ pos +")";
            };
        })
        .styleTween("text-anchor", function(d){
            this._current = this._current || d;
            var interpolate = d3.interpolate(this._current, d);
            this._current = interpolate(0);
            return function(t) {
                var d2 = interpolate(t);
                return midAngle(d2) < Math.PI ? "start":"end";
            };
        });

    text.exit()
        .remove();

    /* ------- SLICE TO TEXT POLYLINES -------*/

    var polyline = svg.select(".lines").selectAll("polyline")
        .data(pie(data), key);

    polyline.enter()
        .append("polyline");

    polyline.transition().duration(1000)
        .attrTween("points", function(d){
            this._current = this._current || d;
            var interpolate = d3.interpolate(this._current, d);
            this._current = interpolate(0);
            return function(t) {
                var d2 = interpolate(t);
                var pos = outerArc.centroid(d2);
                pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
                return [arc.centroid(d2), outerArc.centroid(d2), pos];
            };          
        });

    polyline.exit()
        .remove();
};

</script>
</body>

提前致谢。

【问题讨论】:

    标签: javascript d3.js charts


    【解决方案1】:

    enter、update 和 exit 模式在 d3.js v4 中略有变化。您现在需要合并.merge statement。

    var slice = svg.select(".slices").selectAll("path.slice")
        .data(pie(data), key);
    
    slice.enter()
        .insert("path")
        .style("fill", function(d) { return color(d.data.label); })
        .attr("class", "slice") //<-- enter selection
        .merge(slice) //<-- merge back in update selection
        .transition().duration(1000)
        .attrTween("d", function(d) {
            this._current = this._current || d;
            var interpolate = d3.interpolate(this._current, d);
            this._current = interpolate(0);
            return function(t) {
                return arc(interpolate(t));
            };
        });
    

    更新plunker。

    【讨论】:

      猜你喜欢
      • 2017-03-20
      • 2019-07-18
      • 2013-03-17
      • 1970-01-01
      • 2013-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-26
      相关资源
      最近更新 更多