使用D3.js创建物流地图的示例代码

前端之家收集整理的这篇文章主要介绍了使用D3.js创建物流地图的示例代码前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

本文介绍了使用D3.js创建物流地图的示例代码分享给大家,具体如下:

示例图

制作思路

  1. 需要绘制一张中国地图,做为背景。
  2. 需要主要城市的经纬坐标,以绘制路张起点和终点。
  3. 接收到物流单的城市,绘制一个闪烁的标记
  4. 已经有过物流单的目标城市,不再绘制路线。
  5. 每次新产生一笔物流单,都有一个标记沿路线移向目标的动画效果
  6. 绘制结束后的数据,需要清理掉,以减少对浏览器的资源占用。

开始撸码

1.创建网页模板

加载D3JS,为了方便调试,直接下载d3.js文件在本地,实际使用的时候,可以换成加载路径。注意,使用的是V4版的D3,和V3版有差异。

创建一个DIV块,准备绘图。

<@R_502_338@ charset="utf8">

创建SVG,以下所有代码放在

创建SVG图形分组,以备调用

  1. gmp,保存背景地图和起点标记
  2. mline,保存起点和目标之间的连线,以及目标点。
  3. buttion,测试用的按钮

创建投影函数

  1. 经纬度不能直接用来绘图,需要转换成平面坐标。d3js提供了比较丰富的投影方法,本例中使用了geoEquirectangular()方法
  2. projection 是将经纬度转换为平面坐标的方法
  3. path 是将经纬度转换为连线绘制点坐标的方法(省得自己再写函数构造path路径)

创建marker标记,以便多个连线终点调用

  1. 由于会有多个物流连线的终点,所以都放在一个marker标记调用
  2. 这个标记是由中间的 圆形 + 外圈 构成。外圈的闪烁效果另外创建。
Box","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","5") .attr("fill-opacity","0") .attr("stroke-width","1") .attr("stroke","white");

绘制中国地图,并标记起点(长沙)

地图使用的经纬集为china.json,这个文件网上有很多

标记长沙 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","10") .attr("stroke-width","2") .attr("fill-opacity","0"); });

创建方法,绘制一条从指定起点到终点的连线,并在络点绘制marker标记

  1. 方法需要输入终点城市名称(city)和经纬度(data)
  2. 调用之前建立的project()方法,将终点经纬度转换为平面坐标。
  3. 计算起点(长沙)和终点之前的距离,做为线条长度和动画时间参数。
  4. 在线条上绘制一个圆形标记,并实现从起点到终点的移动动画。
  5. 标记移动到终点后,即删除,节省资源。
  6. 如果线点在之前已经绘制过,则不绘线条,只绘制移动标记
  7. 每处理一次物流单,则城市记录+1。
数量 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(); };

创建动画队例,实现标记外圈的闪烁效果

创建测试按钮和测试的目标城市数据

4038034721766],'益阳':[112.36654664522563,28.58808777988717],'南京':[118.77807440802562,32.05723550180587],'武昌':[114.35362228468498,30.56486029278519],};
// <a href="/tag/suiji/" target="_blank" class="keywords">随机</a>获得目标城市
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]]);
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

猜你在找的JavaScript相关文章