首頁 web前端 js教程 D3.js創建物流地圖

D3.js創建物流地圖

Mar 23, 2018 pm 01:17 PM
javascript 地圖

這次帶給大家D3.js創建物流地圖,D3.js創建物流地圖的注意事項有哪些,下面就是實戰案例,一起來看一下。

範例圖

製作想法

  1. #需要繪製一張中國地圖,做為背景。

  2. 需要主要城市的經緯座標,以繪製路張起點和終點。

  3. 接收到物流單的城市,繪製一個閃爍的標記。

  4. 已經有過物流單的目標城市,不再繪製路線。

  5. 每次新產生一筆物流單,都有一個標記沿著路線移向目標的動畫效果。

  6. 繪製結束後的數據,需要清理掉,以減少對瀏覽器的資源佔用。

開始擼碼

#1.建立網頁範本

載入D3JS,為了方便調試,直接下載d3.js檔案在本地,實際使用的時候,可以換成載入路徑。注意,使用的是V4版的D3,和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,以下所有程式碼放在<script></script>中

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

建立SVG圖形分組,以備呼叫

  1. #gmp,儲存背景地圖和起點標記。

  2. mline,保存起點和目標之間的連線,以及目標點。

  3. buttion,測試用的按鈕

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");
登入後複製

建立投影函數

  1. ##經緯度不能直接用來繪圖,需要轉換成平面座標。 d3js提供了比較豐富的投影方法,本例中使用了geoEquirectangular()方法。

  2. projection 是將經緯度轉換為平面座標的方法

  3. path 是一種將經緯度轉換為連線繪製點座標的方法(省得自己再寫函數建構path路徑)

  4. var projection = d3.geoEquirectangular()
                  .center([465,395]) // 指定投影中心,注意[]中的是经纬度
                  .scale(height)
                  .translate([width / 2, height / 2]);
    var path = d3.geoPath().projection(projection);
    登入後複製

建立marker標記,以便多個連線終點呼叫

    ##由於會有多個物流連線的終點,所以都放在一個marker標記中呼叫。
  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");
    登入後複製
繪製中國地圖,並標記起點(長沙)

地圖使用的經緯集為china.json,這個檔案網路上有很多

// 记录长沙坐标
    var changsha = projection([112.59,28.12]);
    // 读取地图数据,并绘制中国地图
    mapdata = [];
    d3.json('china.json', 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");
    });
登入後複製

建立方法,繪製一條從指定起點到終點的連線,並在絡點繪製marker標記。

    方法需要輸入終點城市名稱(city)和經緯度(data)
  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);
    });
登入後複製

建立測試按鈕和測試的目標城市資料

var cityordinate = {
      '哈尔滨':[126.5416150000,45.8088260000],
      '石家庄':[116.46,39.92],
      '北京':[116.39564503787867,39.92998577808024],
      '上海':[121.480539,31.235929],
      '广州':[113.271431,23.135336],
      '重庆':[106.558434,29.568996],
      '青岛':[120.38442818368189,36.10521490127382],
      '福州':[119.30347,26.080429],
      '兰州':[103.840521,36.067235],
      '贵阳':[106.636577,26.653325],
      '成都':[104.081534,30.655822],
      '西安':[108.946466,34.347269],
      '长春':[125.3306020000,43.8219540000],
      '台湾':[120.961454,23.80406],
      '呼和浩特':[111.7555090000,40.8484230000],
      '澳门':[113.5494640000,22.1929190000],
      '武汉':[114.3115820000,30.5984670000],
      '昆明':[102.71460113878045,25.049153100453159],
      '乌鲁木齐':[87.56498774111579,43.84038034721766],
      '益阳':[112.36654664522563,28.58808777988717],
      '南京':[118.77807440802562,32.05723550180587],
      '武昌':[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]]);
    });
登入後複製

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

JS取得圖片的top N色值方法

使用render方法的圖文詳解

小程式使用.getImageInfo()取得圖片資訊

以上是D3.js創建物流地圖的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何在iPhone中使Google地圖成為預設地圖 如何在iPhone中使Google地圖成為預設地圖 Apr 17, 2024 pm 07:34 PM

iPhone上的預設地圖是Apple專有的地理位置供應商「地圖」。儘管地圖越來越好,但它在美國以外的地區運作不佳。與谷歌地圖相比,它沒有什麼可提供的。在本文中,我們討論了使用Google地圖成為iPhone上的預設地圖的可行性步驟。如何在iPhone中使Google地圖成為預設地圖將Google地圖設定為手機上的預設地圖應用程式比您想像的要容易。請依照以下步驟操作–先決條件步驟–您必須在手機上安裝Gmail。步驟1–開啟AppStore。步驟2–搜尋“Gmail”。步驟3–點選Gmail應用程式旁

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

小紅書如何把店家地址加入地圖?店鋪地址設定怎麼填? 小紅書如何把店家地址加入地圖?店鋪地址設定怎麼填? Mar 29, 2024 am 09:41 AM

隨著小紅書越來越受到年輕人的喜愛,越來越多的人選擇在小紅書上開店。許多新手賣家在設定店家地址時遇到了困難,不知道如何把店家地址加入地圖。一、小紅書如何把店家地址加入地圖? 1.首先,確保您的店鋪在小紅書上有註冊帳號,並且已經成功開設店鋪。 2.登入小紅書帳號,進入店家後台,找到「店舖設定」選項。 3.在店舖設定頁面,找到「店家地址」一欄,點選「新增地址」。 4.在彈出的地址添加頁面,填寫店舖的詳細地址信息,包括省份、城市、區縣、街道、門牌號碼等。 5.填寫完畢後,點選「確認新增」按鈕。小紅書會對您提供的地址

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

See all articles