您好,欢迎访问一九零五行业门户网

D3.js创建物流地图

这次给大家带来d3.js创建物流地图,d3.js创建物流地图的注意事项有哪些,下面就是实战案例,一起来看一下。
示例图
制作思路
需要绘制一张中国地图,做为背景。
需要主要城市的经纬坐标,以绘制路张起点和终点。
接收到物流单的城市,绘制一个闪烁的标记。
已经有过物流单的目标城市,不再绘制路线。
每次新产生一笔物流单,都有一个标记沿路线移向目标的动画效果。
绘制结束后的数据,需要清理掉,以减少对浏览器的资源占用。
开始撸码
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图形分组,以备调用
gmp,保存背景地图和起点标记。
mline,保存起点和目标之间的连线,以及目标点。
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);
创建投影函数
经纬度不能直接用来绘图,需要转换成平面坐标。d3js提供了比较丰富的投影方法,本例中使用了geoequirectangular()方法。
projection 是将经纬度转换为平面坐标的方法
path 是将经纬度转换为连线绘制点坐标的方法(省得自己再写函数构造path路径)
var projection = d3.geoequirectangular()               .center([465,395]) // 指定投影中心,注意[]中的是经纬度               .scale(height)               .translate([width / 2, height / 2]); var path = d3.geopath().projection(projection);
创建marker标记,以便多个连线终点调用
由于会有多个物流连线的终点,所以都放在一个marker标记中调用。
这个标记是由中间的 圆形 + 外圈 构成。外圈的闪烁效果另外创建。
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)
调用之前建立的project()方法,将终点经纬度转换为平面坐标。
计算起点(长沙)和终点之前的距离,做为线条长度和动画时间参数。
在线条上绘制一个圆形标记,并实现从起点到终点的移动动画。
标记移动到终点后,即删除,节省资源。
如果线点在之前已经绘制过,则不绘线条,只绘制移动标记。
每处理一次物流单,则城市记录+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();     };
创建动画队例,实现标记外圈的闪烁效果
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]]);     });
相信看了本文案例你已经掌握了方法,更多精彩请关注其它相关文章!
推荐阅读:
js获取图片的top n色值方法
使用render方法的图文详解
小程序使用.getimageinfo()获取图片信息
以上就是d3.js创建物流地图的详细内容。
其它类似信息

推荐信息