D3.js - 补间弧位置,内半径和外半径 - D3.js弧

时间:2015-06-15 16:10:19

标签: javascript animation svg d3.js tween

我正在尝试研究如何将多个弧补间到新位置,同时根据内半径和外半径改变弧的大小。

意味着它将从画布上的当前位置移动到新位置,同时根据新数据与旧数据相比的变化,变形为新形状。

我已经阅读过许多例如http://bl.ocks.org/mbostock/5100636的例子,这些例子都很棒但是我无法根据我的特殊需要调整任何例子。我发现的大多数示例都不涉及在画布上移动弧。

这里是我如何在第一个工作正常的情况下创建弧,并根据数据动画从0到结束位置的弧。

// THIS IS CALLED ON LOAD OF THE GRAPH
function createLargeArcs(graph,data){
    var arc = d3.svg.arc()
                .innerRadius(function (data) { return (data.r * 5) + 5; })
                .outerRadius(function (data) { return data.r * 5 })
                .startAngle(0);


    var endAngleFunction = function (data) {
        return (data.percentage) * ((2 * Math.PI) / 180);
    };

    // a global variable
    arcGroup = graph.append("g")
        .attr("class", "arcsGroup");

    var arcs = arcGroup.selectAll("path")
                        .data(data)
                        .enter()
                        .append("svg:path")
                        .attr("transform", function (d) { return "translate(" + xScale(d.u) + "," + yScale(d.t) + ")"; })
                        .style("fill", "red");

    arcs.transition()
        .duration(750)
        .call(arcTween);

    // http://bl.ocks.org/mbostock/5100636
    function arcTween(transition, newAngle) {
        transition.attrTween("d", function (d) {
            var interpolate = d3.interpolate(0, endAngleFunction(d));
            return function (t) {
                d.endAngle = interpolate(t);
                return arc(d);
            };
        });
    }
  }
  • 上述所有作品都很好

但它是根据我正在努力解决的新数据值来研究如何将弧线补充到新位置和新尺寸的过程。

到目前为止,我有一个刷新函数,它接受一个新的/更新的数据集,并且在刷新函数中,这是我定位弧元素的补间的地方。 我通过以下方式实现了将所有弧线移动到新位置:

// THIS IS CALLED LATER ON WHEN DATA CHANGES - ITS HERE I NEED TO IMPLEMENT
function refresh(data){

    var arcs = arcGroup.selectAll("path")
                        .data(newData)

    arcs.transition()
        .duration(1000)
        .attr("transform", function(d) { return "translate("+ xScale(d.users) + "," + yScale(d.traffic) + ")"; });
}

非常感谢任何帮助。感谢

1 个答案:

答案 0 :(得分:0)

好的,所以我终于找到了这个用例的最佳方法。从上面的例子可以看出,我能够创建没有问题的弧,但同时跨越位置,半径弧弧度的任务多个弧(在这种情况下为10)它开始变得有点棘手。

大多数示例如http://bl.ocks.org/mbostock/5100636演示了如何根据有效变化的数据转换弧弧度,但是我找不到实现此目的的示例,并且还将弧移动到画布上的新位置也转换弧的半径。也许有一个例子,但我找不到它。所以这就是我如何设法实现所有3个过渡。

    // A helper function to convert a percentage value to radians
    var endAngleFunction = function (d) {
        return (d['percentage-value']) * ((2 * Math.PI) / 180);
    };

    // create an arc object but without setting the "endAngle"
    var arc = d3.svg.arc()
                .innerRadius(function (data) { return (d.r * 5) + 5; }) // calculating the radius based on a value within the data (different for each arc)
                .outerRadius(function (data) { return d.r * 5 })
                .startAngle(0);

    // selecting all svg paths (arcs) within arcGroup, a global variable referencing the group each arc gets appended to when created
    var arcs = arcGroup.selectAll("path")
                        .data(data);

    // transition the position of the arc to its new position
    arcs.transition("position")
        .duration(1000)
        .attr("transform", function(d) { return "translate("+ xScale(d.u) + "," + yScale(d.t) + ")"; });

    // transition the arc radians to new value 
    arcs.transition("newArc")
        .duration(1000)
        .attr("endAngle", function(d) { return endAngleFunction(d); }) // binding the new end Angle to the arc for later reference to work out what previous end angle was
        .transition()
        .delay(500)
        .duration(1000)
        .call(arcTween);

    // A function to tween the arc radians from a value to a new value - inspired by http://bl.ocks.org/mbostock/5100636
    function arcTween(transition, newAngle) {
        transition.attrTween("d", function (d) {
            var interpolate = d3.interpolate(d3.select(this).attr("endAngle"), endAngleFunction(d));
            return function (t) {
                d.endAngle = interpolate(t);
                return arc(d);
            };
        });
    }

注意: 对我来说最重要的是弄清楚如何获得前一个角度并转换到新角度,这是通过将结束角度绑定到弧形对象来实现的。创建和/或修改,以便我可以稍后将其拉入并用于过渡。

这似乎对我很有用。然而,由于我是D3的新手,可能有更有效的方法来实现这一点,甚至可以构建代码或调用事物的顺序。从这里开始,我会尝试收紧这个问题并制定一个更有效的方法。

我希望这可能会在某个阶段对某人有所帮助,因为上帝知道我真的在这个问题上挣扎了一段时间。

感谢所有帮助过此事的人。