如何在D3.js中为地图上的路径设置点动画?

时间:2015-03-18 22:39:27

标签: d3.js

我有一张地图,我已经在地图上成功绘制了一系列LineStrings。

但我真正想做的是在每个LineString定义的路线上设置动画圈。

我看了几个例子(http://bl.ocks.org/zross/6a31f4ef9e778d94c204http://www.tnoda.com/blog/2014-04-02),但我不确定我是如何将圆圈放在起点上,然后让它们沿着路径行进。

这是我绘制路径的地图(红色表示可见性) paths I want points to follow 这是我的代码 - hydro_map是转换为GeoJSON FeatureCollection的shapefile,stations是GeoJSON特征集合(只是点),links是一个LineString数组。我想创建圆圈,然后将它们按照我创建的每条路径进行转换。

var width = 900, height = 800;
var projection = d3.geo.mercator().center([-87.55,41.919]).scale(170000);
var path = d3.geo.path().projection(projection);

var svg = d3.select("#output").append("svg")
    .attr("width", width)
    .attr("height", height)
    .call(d3.behavior.zoom()
    .on("zoom", redraw))
    ;

var g = svg.append("g");
var terrainGroup = g.append("g");
var arcGroup = g.append("g");
var stationGroup = g.append("g");
var tripGroup = g.append("g");

//draw terrain
terrainGroup.append("path")
         .datum({type: "FeatureCollection", features: hydro_map.features})
         .attr("d", path)
         .style("fill", "#3db7e4");

//plot stations
stationGroup.selectAll("circle")
    .data(stations.features).enter()
    .append("path")
    .attr("d", path.pointRadius(0.5));

//draw paths between stations
var pathArcs = arcGroup.selectAll(".arc")
                        .data(links);
pathArcs.enter()
        .append("path")
        .attr({"class": "arc"})
        .style({fill: "none",})
        .attr({d: path})
        .style({
            stroke: "red",
            "stroke-width": "0.5px"
});

1 个答案:

答案 0 :(得分:5)

如果路径是直线,则可以如下所示沿路径移动圆圈。



var svg = d3.select("body")
    .append("svg")
    .attr("width",500)
    .attr("height",500);

var path = svg.append("path")
   .attr("d","M 100 350 l 150 -300")
   .attr("fill","none")
   .attr("stroke","black");

var circle = svg.append("circle")
   .attr("r",5)
   .attr("cx",100)
   .attr("cy",350);

var pathEl = path.node();
for(var i=0;i<pathEl.getTotalLength();i++){
    var pt = pathEl.getPointAtLength(i);
    circle.transition()
        .duration(3500)
        .attr("cx",pt.x)
        .attr("cy",pt.y);
}
&#13;
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
&#13;
&#13;
&#13;

如果路径是曲线,则可以使用attrTween完成任务。

&#13;
&#13;
var svg = d3.select("body")
    .append("svg")
    .attr("width",500)
    .attr("height",500);

var path = svg.append("path")
   .attr("d","M 100 350 q 150 -300 300 0")
   .attr("fill","none")
   .attr("stroke","black").call(transition);

var startPoint = pathStartPoint(path);
 
  var marker = svg.append("circle");
  marker.attr("r", 7)
    .attr("id", "marker")
    .attr("transform", "translate(" + startPoint + ")");
 
  function pathStartPoint(path) {
    var d = path.attr("d"),
    dsplitted = d.split(" ");
    return dsplitted[1];
  }
 
  function transition(path) {
    path.transition()
        .duration(3500)
        .attrTween("stroke", tweenDash)
        //.each("end", function() { d3.select(this).call(transition); }); infinite loop
  }
 
  function tweenDash() {
    var l = path.node().getTotalLength();
    return function(t) {
      var marker = d3.select("#marker");
      var p = path.node().getPointAtLength(t * l);
      marker.attr("transform", "translate(" + p.x + "," + p.y + ")");
      return "black";
    }
  }
&#13;
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
&#13;
&#13;
&#13;