D3.js-补间弧位置,内部半径和外部半径-D3.js弧 [英] D3.js - Tween Arc position, inner Radius and outer Radius - D3.js Arc

查看:102
本文介绍了D3.js-补间弧位置,内部半径和外部半径-D3.js弧的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找出如何在多个弧之间补间到新位置,同时还要根据内部和外部半径更改弧的大小。

I am trying to work out how to tween multiple arcs to new positions, while also changing the size of the arc in terms of its inner and outer radius.

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

Meaning it will move from its current position on the canvas to its new position while also morphing to its new shape based on changes in new data compared to the old data.

I阅读了许多示例,例如 http://bl.ocks.org/mbostock/5100636 太好了,但是我无法根据自己的特殊需要调整任何示例。我发现的大多数示例都没有涉及在画布上移动弧线。

I have read many examples such as http://bl.ocks.org/mbostock/5100636 which are all great however I cannot adapt any example to my particular need. Most examples that Ive found do not involve moving the arc on the canvas.

这是我首先创建圆弧的方法,该方法工作正常,并根据数据将圆弧从0动画到其最终位置。

here is how I am creating the arcs in the first place which is working fine, and also animating the arc from 0 to its end position according to the data.

// 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);
            };
        });
    }
  }




  • 以上所有效果很好

  • 但是它是根据新数据确定如何将弧线过渡到其新位置和新尺寸的过程我一直在努力的价值观。

    But its the process of working out how to tween the arcs to their new positions and their new size based on new data values that I am struggling with.

    到目前为止,我有一个refresh函数,该函数接受新的/更新的数据集,而在refresh函数内,这是我定位弧元素的补间的地方。
    我已经通过以下方法实现了所有弧线向新位置的移动:

    so far I have a refresh function which accepts a new/updated data set and within the refresh function this is where I am targeting the tween of the arc elements. I have achieved the moving of all of the arcs to their new positions with the following :

    // 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) + ")"; });
    }
    

    任何帮助将不胜感激。谢谢

    Any help would be much appreciated. Thanks

    推荐答案

    好的,所以我终于找到了解决此用例的最佳方法。因此,从上面的示例中可以看出,我能够毫无问题地创建弧,但是可以同时跨整个范围移动位置,半径弧度多弧(在这种情况下为10)开始变得有些棘手。

    Okay, so I finally worked out what seems the best approach for this use case. So as you can see from the above example I was able to create the arcs with no issue, but the task of transitioning position, radius and arc radians at the same time across multiple arcs (10 in this case) it started to get a little tricky.

    大多数示例,例如 http:// bl.ocks.org/mbostock/5100636 演示了如何基于有效地更改数据来转换弧度弧度,但是我找不到能实现此目的并且将弧度移动到画布上新位置的示例。过渡圆弧的半径。也许那里有一个例子,但我找不到。因此,这就是我设法实现所有3个过渡的方法。

    Most of the examples such as http://bl.ocks.org/mbostock/5100636 demonstrate how to transition the arc radians based on changing data efficiently, however I could not find an example that achieved this and also moved the arc to a new position on the canvas while also transitioning the radius of the arc. Perhaps there is an example out there but I could not find it. So here is how I managed to achieve all 3 transitions.

        // 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的新手,因此可能会有更有效的方法来实现此目标,甚至构造代码或调用事物的顺序。从这里开始,我将尝试加强这一点,并找到一种更有效的方法。

    And this seemed to work for me just fine. However as I am new to D3 there could be a more efficient way of achieving this or even structuring the code or the order of how things are called. From here I will try tighten this up and work out a more efficient way.

    我希望这可能对某个阶段的人有所帮助,因为上帝知道我确实为此苦了一段时间。

    I hope this might be of help to someone at some stage as god knows I really struggled with this for some time.

    感谢所有为此提供帮助的人。

    Thank you to all who helped on this.

    这篇关于D3.js-补间弧位置,内部半径和外部半径-D3.js弧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆