> 웹 프론트엔드 > JS 튜토리얼 > D3.js에서 물류 지도를 만드는 방법(자세한 튜토리얼)

D3.js에서 물류 지도를 만드는 방법(자세한 튜토리얼)

亚连
풀어 주다: 2018-06-09 11:32:36
원래의
3443명이 탐색했습니다.

이 글에서는 주로 D3.js를 사용하여 물류 지도를 생성하기 위한 샘플 코드를 소개하고 참고용으로 제공합니다.

이 기사에서는 D3.js를 사용하여 물류 지도를 작성하고 모든 사람과 공유하기 위한 샘플 코드를 소개합니다. 중국을 배경으로 그려야 합니다.

도로 시트의 시작점과 끝점을 그리려면 주요 도시의 위도와 경도 좌표가 필요합니다.

물류 주문이 접수된 도시에는 깜박이는 표시가 그려집니다.

  1. 이미 물류주문 대상 도시가 있어 경로는 그려지지 않습니다.

  2. 새로운 물류 주문이 생성될 때마다 마크가 대상까지의 경로를 따라 이동하는 애니메이션 효과가 발생합니다.

  3. 브라우저의 리소스 사용량을 줄이기 위해 그리기 후 데이터를 정리해야 합니다.

  4. 코딩 시작

  5. 1. 웹 페이지 템플릿 만들기

  6. D3JS 로드 실제 사용 시에는 d3.js 파일을 직접 다운로드하여 로드할 수 있습니다. . D3의 V4 버전이 사용되며 이는 V3 버전과 다릅니다.

    그림을 그릴 준비가 된 p 블록을 만듭니다.
  7. <!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 그래픽 그룹화 생성

gmp 호출 준비, 배경 맵 및 시작점 표시 저장.

mline은 시작점과 목표점 사이의 연결은 물론 목표점까지 저장합니다.

버튼, 테스트용 버튼

    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. 투영 기능 만들기

  2. 위도와 경도는 그리기에 직접 사용할 수 없으며 평면 좌표로 변환해야 합니다. d3js는 상대적으로 다양한 투영 방법을 제공합니다. 이 예에서는 geoEquirectangular() 방법이 사용됩니다.
  3. projection은 경도와 위도를 평면 좌표로 변환하는 방법입니다.

path는 선 그리기를 위해 경도와 위도를 점 좌표로 변환하는 방법입니다(직접 경로를 구성하기 위해 함수를 작성할 필요가 없음)

    var projection = d3.geoEquirectangular()
                  .center([465,395]) // 指定投影中心,注意[]中的是经纬度
                  .scale(height)
                  .translate([width / 2, height / 2]);
    var path = d3.geoPath().projection(projection);
    로그인 후 복사
  1. 마커 마커를 생성하여 여러 연결 끝점을 호출할 수 있도록

  2. 물류 연결 끝점이 여러 개 있으므로 모두 마커 태그에서 호출합니다.
  3. 이 마크는 중앙의 원 + 바깥쪽 고리로 구성되어 있습니다. 외부 링의 깜박임 효과는 별도로 생성됩니다.

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");
로그인 후 복사
중국 지도를 그리고 시작점(창사)을 표시합니다.

  1. 지도에 사용된 경도와 위도 설정은 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");
        });
    로그인 후 복사

  2. 생성 방법이 많이 있습니다. 지정된 시작점에서 끝점까지 연결하고 교차점에 마커를 그립니다.
메소드는 목적지 도시명(city)과 경도, 위도(data)를 입력해야 합니다.

이전에 구축한 project() 메소드를 호출하여 목적지 경도, 위도를 평면 좌표로 변환합니다.

시작점(창사)과 끝점 사이의 거리를 선 길이와 애니메이션 시간 매개변수로 계산합니다.

  1. 선에 원형 표시를 그리고 시작점에서 끝점까지의 움직임을 애니메이션화합니다.

  2. 마크가 끝점으로 이동한 후에는 리소스 절약을 위해 삭제됩니다.

  3. 이전에 선점이 그려져 있었다면 선은 그려지지 않고 움직이는 표시만 그려집니다.

  4. 물류 주문이 처리될 때마다 도시 기록이 +1됩니다.

  5. // 创建对象,保存每个城市的物流记录数量
        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();
        };
    로그인 후 복사
  6. 마크 외곽 원의 깜박임 효과를 얻기 위한 애니메이션 팀 예제 만들기

    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);
        });
    로그인 후 복사

    테스트 버튼 만들기 및 대상 도시 데이터 테스트하기
  7. 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]]);
        });
    로그인 후 복사
  8. 위 내용은 모두를 위해 편집한 내용입니다. 앞으로는 모두에게 도움이 되세요.

    관련 기사:
  9. Baidu Maps를 사용하여 지도 그리드를 구현하는 방법

nodejs에서 Express와 Koa2의 비교 및 ​​구별(자세한 튜토리얼)

JS의 싱글톤 모드는 추가, 삭제, 수정 및 쿼리를 구현합니다. 데이터

위 내용은 D3.js에서 물류 지도를 만드는 방법(자세한 튜토리얼)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿