ホームページ  >  記事  >  ウェブフロントエンド  >  D3.js で物流マップを作成する方法 (詳細なチュートリアル)

D3.js で物流マップを作成する方法 (詳細なチュートリアル)

亚连
亚连オリジナル
2018-06-09 11:32:363301ブラウズ

この記事では、D3.js を使用して物流マップを作成するためのサンプル コードを主に紹介します。

この記事では、D3.jsを使用して物流マップを作成するサンプルコードを紹介し、皆さんに共有します。詳細は次のとおりです:

サンプルマップ

制作アイデア

  1. 中国を背景として描く必要があります。

  2. 道路シートの始点と終点を描画するには、主要都市の緯度と経度の座標が必要です。

  3. 物流を受注した都市が点滅マークを描きます。

  4. 物流オーダーの対象都市が既に存在するため、ルートは描画されません。

  5. 新しい物流注文が生成されるたびに、ターゲットまでのルートに沿ってマークが移動するアニメーション効果が発生します。

  6. ブラウザのリソース使用量を減らすために、描画後のデータをクリーンアップする必要があります。

コーディングを開始します

1. Web ページテンプレートを作成します

デバッグを容易にするために、d3.js ファイルをローカルにダウンロードします。 。 D3 の V4 バージョンが使用されるため、V3 バージョンとは異なることに注意してください。

P ブロックを作成し、描画の準備をします。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf8">
    <script type="text/javascript" src="../../static/d3/d3.js"></script>
    <title>地图</title>
  </head>
  <body>
    <p class="fxmap">
    </p>
  </body>
  <script type="text/javascript"></script>
</html>

SVGを作成します。以下のコードはすべて3f1c4e4b6b16bbbd69b2ee476dc4f83a2cacc6d41bbb37262a98f745aa00fbf0に配置されます。

var width=1000 , height=800; // 定义SVG宽高
var svg = d3.select("body p.fxmap")
            .append("svg")
            .attr("width", "width) 
            .attr("height", height)
            .style("background","#000"); //

gmpを呼び出す準備としてSVGグラフィックスのグループを作成し、背景マップと開始点マークを保存します。

  1. mline は、始点とターゲットの間の接続およびターゲット ポイントを保存します。

  2. ボタン、テスト用ボタン

  3. gmap = svg.append("g").attr("id", "map").attr("stroke", "white").attr("stroke-width",1);
        mline = svg.append("g").attr("id", "moveto").attr("stroke", "#FFF").attr("stroke-width", 1.5).attr("fill","#FFF");
        button = svg.append("g").attr("id", "button").attr("stroke", "white").attr("stroke-width", 1).attr("fill", "white");
  4. 投影関数の作成

緯度と経度は描画に直接使用できないため、平面座標に変換する必要があります。 d3js は、比較的豊富な投影メソッドを提供します。この例では、 geoEquirectangular() メソッドが使用されます。

  1. 投影は経度と緯度を平面座標に変換するメソッドです

  2. パスは経度と緯度を線描画用の点座標に変換するメソッドです(パスを構築するための関数を自分で作成する必要がありません)

  3. var projection = d3.geoEquirectangular()
                  .center([465,395]) // 指定投影中心,注意[]中的是经纬度
                  .scale(height)
                  .translate([width / 2, height / 2]);
    var path = d3.geoPath().projection(projection);
  4. 複数の接続エンドポイントを呼び出せるように、マーカー マーカーを作成します

複数の物流接続エンドポイントがあるため、それらはすべてマーカー タグで呼び出されます。

  1. このマークは真ん中の円+外側のリングで構成されています。外輪の点滅効果は別途作成します。

  2. marker = svg.append("defs")
              .append("marker")
              .append("marker")
              .attr("id", "pointer")
              .attr("viewBox","0 0 12 12")  // 可见范围
              .attr("markerWidth","12")    // 标记宽度
              .attr("markerHeight","12")    // 标记高度
              .attr("orient", "auto")     //
              .attr("markerUnits", "strokeWidth") // 随连接线宽度进行缩放
              .attr("refX", "6")       // 连接点坐标
              .attr("refY", "6")
        // 绘制标记中心圆
        marker.append("circle")
            .attr("cx", "6")
            .attr("cy", "6")
            .attr("r", "3")
            .attr("fill", "white");
        // 绘制标记外圆,之后在timer()中添加闪烁效果
        marker.append("circle")
            .attr("id", "markerC")
            .attr("cx", "6")
            .attr("cy", "6")
            .attr("r", "5")
            .attr("fill-opacity", "0")
            .attr("stroke-width", "1")
            .attr("stroke", "white");
  3. 中国の地図を描き、出発点(長沙)をマークします

地図で使用される経度と緯度のセットはchina.jsonです。描画する

// 记录长沙坐标
    var changsha = projection([112.59,28.12]);
    // 读取地图数据,并绘制中国地图
    mapdata = [];
    d3.json(&#39;china.json&#39;, function(error, data){
      if (error)
        console.log(error);
      // 读取地图数据
      mapdata = data.features;
      // 绘制地图
      gmap.selectAll("path")
        .data(mapdata)
        .enter()
        .append("path")
        .attr("d", path);
      // 标记长沙
      gmap.append("circle").attr("id","changsha")
        .attr("cx", changsha[0])
        .attr("cy", changsha[1])
        .attr("r", "6")
        .attr("fill", "yellow")
      gmap.append("circle").attr("id","changshaC")
        .attr("cx", changsha[0])
        .attr("cy", changsha[1])
        .attr("r", "10")
        .attr("stroke-width", "2")
        .attr("fill-opacity", "0");
    });
の作成方法はインターネット上にたくさんあります。指定した始点から終点までのリンクを作成し、交点にマーカーを描画します。

メソッドでは、目的地の都市名(city)と経度・緯度(データ)の入力が必要です

  1. 事前に確立したproject()メソッドを呼び出して、目的地の経度・緯度を平面座標に変換します。

  2. 始点(長沙)と終点の間の距離を線の長さとアニメーション時間のパラメータとして計算します。

  3. ライン上に円形のマークを描き、始点から終点までの動きをアニメーションさせます。

  4. マークは終点に移動した後、リソース節約のため削除されます。

  5. 以前に線点が描画されている場合、線は描画されず、移動マークのみが描画されます。

  6. 物流注文が処理されるたびに、都市レコードは +1 されます。

  7. // 创建对象,保存每个城市的物流记录数量
        var citylist = new Object();
        // 创建方法,输入data坐标,绘制发射线
        var moveto = function(city, data){
          var pf = {x:projection([112.59,28.12])[0], y:projection([112.59,28.12])[1]};
          var pt = {x:projection(data)[0], y:projection(data)[1]};
          var distance = Math.sqrt((pt.x - pf.x)**2 + (pt.y - pf.y)**2);
          if (city in citylist){
            citylist[city]++;
          }else{
            mline.append("line")
                .attr("x1", pf.x)
                .attr("y1", pf.y)
                .attr("x2", pt.x)
                .attr("y2", pt.y)
                .attr("marker-end","url(#pointer)")
                .style("stroke-dasharray", " "+distance+", "+distance+" ")
                .transition()
                .duration(distance*30)
                .styleTween("stroke-dashoffset", function(){
                  return d3.interpolateNumber(distance, 0);
                });
            citylist[city] = 1;
          };
          mline.append("circle")
            .attr("cx", pf.x)
            .attr("cy", pf.y)
            .attr("r", 3)
            .transition()
            .duration(distance*30)
            .attr("transform", "translate("+(pt.x-pf.x)+","+(pt.y-pf.y)+")")
            .remove();
        };
  8. マークの外側の円の点滅効果を実現するアニメーションチームのサンプルを作成します

    var scale = d3.scaleLinear();
        scale.domain([0, 1000, 2000])
          .range([0, 1, 0]);
        var start = Date.now();
        d3.timer(function(){
          var s1 = scale((Date.now() - start)%2000);
          // console.log(s1);
          gmap.select("circle#changshaC")
            .attr("stroke-opacity", s1);
          marker.select("circle#markerC")
            .attr("stroke-opacity", s1);
        });

    テストボタンを作成し、ターゲット都市データをテストします
  9. var cityordinate = {
          &#39;哈尔滨&#39;:[126.5416150000,45.8088260000],
          &#39;石家庄&#39;:[116.46,39.92],
          &#39;北京&#39;:[116.39564503787867,39.92998577808024],
          &#39;上海&#39;:[121.480539,31.235929],
          &#39;广州&#39;:[113.271431,23.135336],
          &#39;重庆&#39;:[106.558434,29.568996],
          &#39;青岛&#39;:[120.38442818368189,36.10521490127382],
          &#39;福州&#39;:[119.30347,26.080429],
          &#39;兰州&#39;:[103.840521,36.067235],
          &#39;贵阳&#39;:[106.636577,26.653325],
          &#39;成都&#39;:[104.081534,30.655822],
          &#39;西安&#39;:[108.946466,34.347269],
          &#39;长春&#39;:[125.3306020000,43.8219540000],
          &#39;台湾&#39;:[120.961454,23.80406],
          &#39;呼和浩特&#39;:[111.7555090000,40.8484230000],
          &#39;澳门&#39;:[113.5494640000,22.1929190000],
          &#39;武汉&#39;:[114.3115820000,30.5984670000],
          &#39;昆明&#39;:[102.71460113878045,25.049153100453159],
          &#39;乌鲁木齐&#39;:[87.56498774111579,43.84038034721766],
          &#39;益阳&#39;:[112.36654664522563,28.58808777988717],
          &#39;南京&#39;:[118.77807440802562,32.05723550180587],
          &#39;武昌&#39;:[114.35362228468498,30.56486029278519],
        };
    
        // 随机获得目标城市
        var cityname = [], total = 0;
        for (var key in cityordinate){
          cityname[total++] = key;
        };
        
        // 创建操作按钮,每次点击发射一条物流线
        button.append("circle")
            .attr("cx", width*0.9)
            .attr("cy", height*0.8)
            .attr("r", width/20)
            .attr("text","click")
            .attr("fill", "grey");
        button.append("text")
            .attr("x", width*0.87)
            .attr("y", height*0.81)
            .style("font-size", "30px")
            .text("click");
        button.on("click", function(){
          var _index = ~~(Math.random() * total);
          moveto(cityname[_index], cityordinate[cityname[_index]]);
        });
上記は、皆さんのためにまとめたものです。今後も皆様のお役に立ちますように。

関連記事:

Baidu Mapを使用してマップグリッドを実装する方法

nodejsでのExpressとKoa2の比較と区別(詳細なチュートリアル)

JSのシングルトンモードは追加、削除、変更、クエリを実装しますデータ

以上がD3.js で物流マップを作成する方法 (詳細なチュートリアル)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。