如何使d3并发转换工作?

时间:2018-02-08 21:20:47

标签: javascript d3.js

我已经开始这样做作为学习D3的辅助项目。所以请放轻松我;

目标: 制作互动机场地图。当鼠标飞过城市时,飞机将从该城市的机场起飞并降落到目的地。

我跟随的步骤;

  1. 我已经将国家和机场数据下载为geojson并在D3上定义了基本地图。
  2. basemap

    1. 我已经编写了必要的函数来导出在转换中使用的空间信息。如果你有时间,可以查看here的代码。
    2. 我已添加过渡到飞机。
    3. transitions

      问题:当我从一个城市乘坐多架飞机时,它只是不动。相反,它会一直保持在同一位置,直到转换结束。 我无法向对象添加并发转换。

      error

      我的过渡功能就像;

      function myTransition(destPoi, originPoi) {
      var tr_bl = true;
      pathData = []; t_dest_poi = [];
      if (tr_bl) {
      //Origin destination coordinates taken from the Origin Poi
      originPoint[0] = originPoi[1];
      originPoint[1] = originPoi[2];
      originPoint = geoMercator(originPoint);//Need transformation before using on screen.
      var lineGenerator = d3.line().curve(d3.curveCatmullRom);
      // Destination coordinate pairs transformed to screen coordinates
      // and assigned to an array 
      for (i = 0; i < destPoi.length; i++) {
        t_dest_poi[i] = geoMercator(destPoi[i]);
      }
      //appending new group g2 with id fp 
      var g2 = map_svg.append("g").attr("id", "fp");
      
      // Creating the planes and flight paths programmatically.*************************************
      for (i = 0; i < destPoi.length; i++) {
        var plane = map_svg.append("path")
          .attr("class", "plane")
          .attr("d", "m25.21488,3.93375c-0.44355,0 -0.84275,0.18332 -1.17933,0.51592c-0.33397,0.33267 -0.61055,0.80884 -0.84275,1.40377c-0.45922,1.18911 -0.74362,2.85964 -0.89755,4.86085c-0.15655,1.99729 -0.18263,4.32223 -0.11741,6.81118c-5.51835,2.26427 -16.7116,6.93857 -17.60916,7.98223c-1.19759,1.38937 -0.81143,2.98095 -0.32874,4.03902l18.39971,-3.74549c0.38616,4.88048 0.94192,9.7138 1.42461,13.50099c-1.80032,0.52703 -5.1609,1.56679 -5.85232,2.21255c-0.95496,0.88711 -0.95496,3.75718 -0.95496,3.75718l7.53,-0.61316c0.17743,1.23545 0.28701,1.95767 0.28701,1.95767l0.01304,0.06557l0.06002,0l0.13829,0l0.0574,0l0.01043,-0.06557c0,0 0.11218,-0.72222 0.28961,-1.95767l7.53164,0.61316c0,0 0,-2.87006 -0.95496,-3.75718c-0.69044,-0.64577 -4.05363,-1.68813 -5.85133,-2.21516c0.48009,-3.77545 1.03061,-8.58921 1.42198,-13.45404l18.18207,3.70115c0.48009,-1.05806 0.86881,-2.64965 -0.32617,-4.03902c-0.88969,-1.03062 -11.81147,-5.60054 -17.39409,-7.89352c0.06524,-2.52287 0.04175,-4.88024 -0.1148,-6.89989l0,-0.00476c-0.15655,-1.99844 -0.44094,-3.6683 -0.90277,-4.8561c-0.22699,-0.59493 -0.50356,-1.07111 -0.83754,-1.40377c-0.33658,-0.3326 -0.73578,-0.51592 -1.18194,-0.51592l0,0l-0.00001,0l0,0z")
          .style("opacity", 1)
          .style("fill", "transparent");
        //creating flight path data with line generator
        pathData[i] = lineGenerator([originPoint, t_dest_poi[i]]);
        //appending created flight path to variable 
        var path = g2.append("path").data([
          [originPoint],
          [t_dest_poi[i]]
        ]).attr("d", d3.line());
      //flight path
        g2.selectAll('path')
          .data([
            [originPoint],
            [t_dest_poi[i]]
          ])
          .attr('d', pathData)
          .attr("stroke", "blue")
          .attr("fill", "transparent");
      
        plane.style("fill", "grey");
      
        var route = g2.append("path")
          .datum({
            type: "LineString", coordinates: [
              [originPoint],
              [t_dest_poi[i]]]
          })
          .attr("class", "route")
          .attr("d", geoPath)
          .attr("stroke", "blue")
          .attr("fill", "transparent");
      
        // adding transition to plane
        plane.transition()
          .duration(5000)
          .attrTween("transform", translateAlong([originPoint, t_dest_poi[i]], path.node()))
          .remove();
          }
      }
      else {
      }}
      
      function translateAlong(co, path) {
      var l = path.getTotalLength();
      return function (d, i, a) {
      return function (t) {
        var p = path.getPointAtLength(t * l);
        [a1, b1] = co[0];
        [a2, b2] = co[1];
        aci = Math.atan((b2 - b1) / (a2 - a1));
        aci = aci * 180 / Math.PI;
        if (a2 > a1) {
          aci = aci + 90;
        } else {
          aci = aci - 90;
        }
        return "translate(" + (p.x) + "," + (p.y) + ") scale(" + Math.sin(Math.PI * t) + ") rotate(" + aci + ")";
      };
      };
      }
      

1 个答案:

答案 0 :(得分:3)

这似乎是在转换期间更新#fp元素的路径的问题。在这种情况下,相对简单的解决方法是分别处理转换。

在你的代码中,在第58-63行的basemap.js中,在for循环中填充数组后,在多个元素的数组上调用myTransition()。

for (i = 0; i <= n - 1; i++) {
  fp[i] = [destAirportObjects[i][1], destAirportObjects[i][2]];
}
myTransition(fp, OriginAirport);

在for循环中调用该函数,转换工作正常:

for (i = 0; i <= n - 1; i++) {
  fp[i] = [destAirportObjects[i][1], destAirportObjects[i][2]];
    myTransition([fp[i]], OriginAirport);
}

如果您选择此解决方案,则应更新myTransition()以获取一组坐标以使代码更易于理解。

或者,不要对basemap.js文件进行任何更改,而是更新myTransition,以便在目标for循环中完成组(var g2)的创建。以下是您在move.js中从第21行开始的内容:

var g2 = map_svg.append("g").attr("id", "fp");

// Creating the planes and flight paths programmatically.*************************************
for (i = 0; i < destPoi.length; i++) {
  //creating flight path data with line generator
  pathData[i] = lineGenerator([originPoint, t_dest_poi[i]]);
  //continue with loop

这导致每次我们遍历循环时都会覆盖g2变量。需要为每个转换/路径创建一个不同的组。

// Creating the planes and flight paths programmatically.*************************************
for (i = 0; i < destPoi.length; i++) {
  var g2 = map_svg.append("g").attr("class", "fp");
  //creating flight path data with line generator
  pathData[i] = lineGenerator([originPoint, t_dest_poi[i]]);
  //continue with loop

最后,由于在这种情况下有多个元素,“fp”应该是var g2的类,而不是ID。请记住相应地更新您的访问者。

修改:以下是method #1method #2

的示例