1

我正在尝试创建类似于此 http://demo.joostkiens.com/het-parool-4g/的内容

报警跳动点

绘制的圆圈有向外跳动的外线。

这是我到目前为止的演示。

http://jsfiddle.net/NYEaX/95/

我用一些虚拟数据绘制了圆圈。顶部是红色圆圈。如何根据警报数据调用动画并使其更加生动......例如。警报级别。

我不确定如何创建一个循环动画,其半径从圆周上弹回然后淡出 - 基于警报级别阈值具有这种多样性

理想情况下,需要像这样在循环中发生转换。http://jsfiddle.net/pnavarrc/udMUx/

var speedLineGroup = sampleSVG.append("g")
                                        .attr("class", "speedlines");

                            speedLineGroup.selectAll("circle.dl-speed-static")
                                .data(dataset)
                                .enter().append("circle")
                                .style("stroke", "red")
                                .style("fill", "black")
                                .attr("r", function(d){
                                    return d.value;
                                })
                                .attr("cx", function(d){
                                    return d.xcoord;
                                })
                                .attr("cy", function(d){
                                    return d.ycoord;
                                })
                                .attr("class", "dl-speed-static")
                                .attr("stroke-opacity", function (e) {
                                    return 1;
                                    //return var
                                })
                                .attr("fill-opacity", function (e) {
                                    return 1;
                                    //return var
                                })
                                .transition()
                                .ease("linear")
                                .duration(200)
                                .attr("r", function (e) {
                                    return 1;
                                    //return var
                                })

我已经合并了帖子中的想法。我已将环创建放在它自己的函数中并删除了超时。我也开始尝试挂钩每个标记的警报阈值。

http://jsfiddle.net/NYEaX/102/

但该应用程序似乎仍然延迟/错误 - 不像主要示例中那样非常清楚。这如何进一步改进。一些警报计数很低 - 但这种方法会导致铃声过早地跳动或闪烁。几乎就像我需要反转该值以获得低警报 - 创建较慢的响应。

            function makeRings() {
                var datapoints = circleGroup.selectAll("circle");
                var radius = 1;

                    function myTransition(circleData){

                        var transition = d3.select(this).transition();

                            speedLineGroup.append("circle")
                              .attr({"class": "ring",
                                     "fill":"red",
                                     "stroke":"red",
                                     "cx": circleData.xcoord,
                                     "cy": circleData.ycoord,
                                     "r":radius,
                                     "opacity": 0.4,
                                     "fill-opacity":0.1
                                    })
                              .transition()
                              .duration(function(){                 
                                return circleData.alarmLevel*100;
                              })
                              .attr("r", radius + 100 )
                              .attr("opacity", 0)
                              .remove();


                        transition.each('end', myTransition);
                    }

              datapoints.each(myTransition);
            } 

这是最新的代码..

makeRings()

var t = window.setInterval(makeRings, 10000);

                function makeRings() {
                        var datapoints = mapSVG.selectAll("circle.location");
                        var radius = 1;

                            function myTransition(circleData){

                                console.log("circleData", circleData);

                                var transition = d3.select(this).transition();

                                    speedLineGroup.append("circle")
                                      .attr({"class": "ring",
                                             "fill":"red",
                                             "stroke":"red",
                                             "cx": circleData.x * ratio,
                                             "cy": circleData.y * ratio,
                                             "r":radius,
                                             "opacity": 0.4,
                                             "fill-opacity":0.1
                                            })
                                      .transition()
                                      .duration(function(){                 
                                        return (circleData.redSum * 100);
                                      })
                                      .attr("r", radius + 30 )
                                      .attr("opacity", 0)
                                      .remove();


                                transition.each('end', myTransition);
                            }

                      datapoints.each(myTransition);
                    } 
4

2 回答 2

1

您链接到的示例使用缩小的代码,因此弄清楚他们在做什么有点痛苦。但是,如果您只观察 DOM 检查器中的变化,您会看到每个环都是一个新的圆圈,它会被添加、变大并背对着,然后被移除。不同的点在环消失之前有多大(因此一次可见多少个环,因为它们都以相同的速度增长)。

我将采取的使这种情况无限期地继续下去的方法是:

  1. 使用'setInterval' 定期调用一个函数(例如,每秒一次或两次),这将在每个数据圈周围创建一个新环。

  2. 使用对数据圈的调用创建环.each(),但将它们添加到不同的<g>元素,和/或使用不同的类名,这样环和数据点之间就不会混淆。

  3. 将环的初始半径设置为与数据点相同,然后立即在其上开始过渡。使过渡的持续时间成为相关数据圆的“强度”数据值的函数,并使最终半径成为该数据值的函数。还将不透明度转换为值 0。

  4. 为环制作过渡的最后一行,.remove()以便每个环在完成扩展后自行移除。

基本代码:

window.setInterval(makeRings, 1000);

function makeRings() {

  datapoints.each(function(circleData){  
       //datapoints is your d3 selection of circle elements

    speedLineGroup.append("circle")
      .attr({"class": "ring",
             "fill":"red", //or use CSS to set fill and stroke styles
             "stroke":"red",
             "cx": circleData.xCoord,
             "cy": circleData.yCoord,
                 //position according to this circle's position
             "r":radius, //starting radius, 
                         //set according to the radius used for data points
             "opacity": 0.8, //starting opacity
             "fill-opacity":0.5 //fill will always be half of the overall opacity
            })
      .transition()
      .duration( intensityTimeScale(circleData.intensity) )
          //Use an appropriate linear scale to set the time it takes for 
          //the circles to expand to their maximum radius.
          //Note that you *don't* use function(d){}, since we're using the data
          //passed to the .each function from the data point, not data
          //attached to the ring
      .attr("r", radius + intensityRadiusScale(circleData.intensity) )
          //transition radius
          //again, create an appropriate linear scale
      .attr("opacity", 0) //transition opacity
      .remove(); //remove when transition is complete

  });
}

因为半径的变化和过渡的持续时间都是强度值的线性函数,所以所有数据点的变化速度都是恒定的。

于 2014-02-13T20:45:23.400 回答
0

在 d3 中创建循环转换所需要做的就是end在转换上使用回调。创建两个函数,每个函数都会在数据上创建一个转换,一个从起点到终点,另一个返回,并让它们在完成时相互调用,如下所示:

function myTransition(d){
    var transition = d3.select(this).transition();

    //Forward transition behavior goes here
    //Probably create a new circle, expand all circles, fade out last circle

    transition.each('end', myTransition); //This calls the backward transition
}

d3.select('myFlashingElement').each(myTransition);

这将封装所有内容,并在您的过渡期间持续循环。下一个过渡总是会在过渡结束之前触发,因此您不必担心同步任何内容。

于 2014-02-13T21:52:34.780 回答