如何将文本过渡应用于d3中的数字

时间:2018-11-22 15:51:47

标签: d3.js

我是d3的新手。我创建了条形图。在条形图中添加带有动画的文本和百分比。当绘制条形图时,数字和百分比将从下到上到达所需位置。这是代码

svg.selectAll(".bar")
    .data(data)
    .enter()
    .append("g")
    .attr("class", "g rect")
    .append("rect")
    .attr("class", "bar")
    .attr("x", function(d) { return x(d.label); })
    .attr("y", h)
    .on("mouseover", onMouseOver) //Add listener for the mouseover event
    ... // attach other events
    .transition()
    .ease(d3.easeLinear)
    .duration(2000)
    .delay(function (d, i) {
        return i * 50;
    })
    .attr("y", function(d) { return y(d.percentage.slice(0, -1)); })
    .attr("width", x.bandwidth() - 15)  // v4’s console.log(bands.bandwidth()) replaced v3’s console.log(bands.rangeband()).
    .attr("height", function(d) { return h - y(d.percentage.slice(0, -1)); })   // use .slice to remove percentage sign at the end of number
    .attr("fill", function(d) { return d.color; });

    var legend = svg.append("g");

    svg.selectAll(".g.rect").append("text")
        .text(function(d) { return d.value })
        .attr("x", function(d) { return x(d.label) + x.bandwidth() / 2 - 15; })
        .attr("y", h)
        .transition()
        .ease(d3.easeLinear)
        .duration(2000)
        .attr("y", function(d) { return y(d.percentage.slice(0, -1) / 2);})         // use slice to remove percentage sign from the end of number
        .attr("dy", ".35em")
        .style("stroke", "papayawhip")
        .style("fill", "papayawhip");

    svg.selectAll(".g.rect").append("text")
        .text(function(d) { return d.percentage; })
        .attr("x", function(d) { return x(d.label) + x.bandwidth() / 2 - 20; })
        .attr("y", h)
        .transition()
        .ease(d3.easeLinear)
        .duration(2000)
        .attr("y", function(d) { return y(d.percentage.slice(0, -1)) - 10; })       // use slice to remove percentage sign from the end of number
        .attr("dy", ".35em")
        .attr("fill", function(d) { return d.color; });

现在,我想应用文本过渡。喜欢而不是仅说90%(d.percentage)。我希望它从0开始逐渐达到d.percentage。在这种情况下,如何应用文本过渡。我尝试了以下操作,但没有成功

svg.selectAll(".g.rect").append("text")
.text(function(d) { return d.percentage; })
.attr("x", function(d) { return x(d.label) + x.bandwidth() / 2 - 20; })
.attr("y", h)
.transition()
.ease(d3.easeLinear)
.duration(2000)
.tween("text", function(d) {
        var i = d3.interpolate(0, d.percentage.slice(0, -1));
        return function(t) {
            d3.select(this).text(i(t));
        };
})
.attr("y", function(d) { return y(d.percentage.slice(0, -1)) - 10; })       // use slice to remove percentage sign from the end of number
.attr("dy", ".35em")
.attr("fill", function(d) { return d.color; });

2 个答案:

答案 0 :(得分:1)

问题是this值。

将其保存在闭包(that)中。

使用数字插值器,以便将结果四舍五入到小数位数。

var ptag = d3.select('body').append('p');

ptag.transition()
  .ease(d3.easeLinear)
  .duration(2000)
  .tween("text", function(d) {
    var that = this;
    var i = d3.interpolate(0, 90);  // Number(d.percentage.slice(0, -1))
    return function(t) {
        d3.select(that).text(i(t).toFixed(2));
    };
  })
<script src="https://d3js.org/d3.v5.min.js"></script>

答案 1 :(得分:0)

您的问题是您return function(t) { ... }并尝试访问其中的父函数this。解决方案是返回箭头函数,该函数不会遮盖this值:

return t => d3.select(this).text(i(t));

(顺便说一句,您可能还想在打印之前四舍五入百分比)

-------------编辑--------------

这是工作代码

var numberFormat = d3.format("d");

svg.selectAll(".g.rect").append("text")
.attr("x", function(d) { return x(d.label) + x.bandwidth() / 2 - 20; })
.attr("y", h)
.transition()
.ease(d3.easeLinear)
.duration(2000)
.tween("text", function(d) {
        var element = d3.select(this);
        var i = d3.interpolate(0, d.percentage.slice(0, -1));
        return function(t) {
            var percent = numberFormat(i(t));
            element.text(percent + "%");
        };
        //return t => element.text(format(i(t)));
})
.attr("y", function(d) { return y(d.percentage.slice(0, -1)) - 10; })       // use slice to remove percentage sign from the end of number
.attr("dy", ".35em")
.attr("fill", function(d) { return d.color; });

谢谢:)