【数据可视化】 D3+ArcGIS 迁徙图实现

概述

用D3和ArcGIS结合做效果已经将近一年的时间,却一直没有时间整理博客,将知识分享,终于,我的第一遍博客将迎来了。

效果图

具体流程

1.svg叠合ArcGIS Server发布的地图服务叠加展示,在ArcGIS Server的地图中有一个svg标签可以供D3来绘制。

var poitMoveSvg = d3.select("#" + map.id + "_gc")

2.用svg的animateMotion标签来创建path路径,达到小圆圆的按照路径移动效果

g.append("circle")
  .attr("r", 5)
   .attr("fill", colorArr[2])
   .append('animateMotion')
   .attr('path', path)
   .attr('rotate', "auto")
   .attr('dur', "10s")
   .attr('repeatCount', "indefinite");

rotate:auto自动旋转方向
dur:路径运行完成时间
repeatCount:重复次数

3.svg的pauseAnimations与unpauseAnimations属性控制断点可以继续运动,保证缩放和平移可以不出现间断

/让动画时间停止
document.getElementById("d3_svg").pauseAnimations()
//开始动画
document.getElementById("d3_svg").unpauseAnimations()

4.添加地图缩放和平移事件,重新整理数据进行更新

if (zoomEvent_e == null) {
    zoomEvent_e = map.on("zoom-end", mig1);
}
if (zoomEvent_s == null) {
    zoomEvent_s = map.on("zoom-start", d3Clear);
}
if (panEvent_e == null) {
    panEvent_e = map.on("pan-end", mig1);
}
if (panEvent_s == null) {
    panEvent_s = map.on("pan-start", d3Clear);
}

5.点移动源代码,仅供参考

/清除按钮,清除事件
    function clearClick() {
        zoomEvent_s.remove()
        zoomEvent_e.remove()
        panEvent_s.remove()
        panEvent_e.remove()
        zoomEvent_s = null;
        zoomEvent_e = null;
        panEvent_s = null;
        panEvent_e = null;
        d3.selectAll("#pointMove").remove();
        d3.selectAll("#d3_svg").remove();
    }


    //----------------------------------分割--------------------------------------------
    //点移动
    var migData1 = [
        [{
            x: 110.85099,
            y: -74.25962166
        }, {
            x: 134.537944,
            y: -99.363874
        }],
        [{
            x: 30.98670782,
            y: -60.99922008
        }, {
            x: 30.98670782,
            y: -51.998
        }, {
            x: 84.678,
            y: -53.744
        }, {
            x: 85.101,
            y: -56.739
        }],
        [{
            x: 30.98670782,
            y: -60.99922008
        }, {
            x: 30.98670782,
            y: -50.998
        }, {
            x: 84.678,
            y: -52.744
        }, {
            x: 93.25,
            y: -40.759
        }]
    ];

    function d3Clear() {
        d3.selectAll("#pointMove").remove();
    }

    function play() {
        //        给svg标签transform属性,让svg没有偏移
        var poitMoveSvg = d3.select("#" + map.id + "_gc")
            .attr("class", "svgTransform")
            .append("svg")
            .attr("id", "d3_svg");
        mig1()

        function mig1() {
            d3.selectAll("#pointMove").remove();
            //让动画时间停止
            document.getElementById("d3_svg").pauseAnimations()
            if (zoomEvent_e == null) {
                zoomEvent_e = map.on("zoom-end", mig1);
            }
            if (zoomEvent_s == null) {
                zoomEvent_s = map.on("zoom-start", d3Clear);
            }
            if (panEvent_e == null) {
                panEvent_e = map.on("pan-end", mig1);
            }
            if (panEvent_s == null) {
                panEvent_s = map.on("pan-start", d3Clear);
            }
            //将数据变为屏幕坐标
            for (var i = 0; i < migData1.length; i++) {
                screenData = [];
                for (var index = 0; index < migData1[i].length; index++) {
                    screenData.push(map.toScreen(migData1[i][index]));
                }

                g = d3.select("#d3_svg")
                    .append("g")
                    .attr("id", "pointMove");
                //循环轨迹每一点生成path
                var path = ''
                for (var j = 0; j < screenData.length; j++) {
                    path += j == 0 ? ('M' + screenData[j].x + ',' + screenData[j].y) : ('L' + screenData[j].x + ',' +
                        screenData[j].y)
                }
                g.append("path")
                    .attr("d", path)
                    .attr("stroke", colorArr[0]) //颜色
                    .attr("fill", "none")
                    .attr("stroke-width", "2");
                g.append("circle")
                    .attr("r", 5)
                    .attr("fill", colorArr[2])
                    .append('animateMotion')
                    .attr('path', path)
                    .attr('rotate', "auto")
                    .attr('dur', "10s")
                    .attr('repeatCount', "indefinite");
                //开始动
                document.getElementById("d3_svg").unpauseAnimations()
            }
        }
    }    

原文链接


技术博客
CSDN:http://blog.csdn.NET/gisshixisheng
博客园:http://www.cnblogs.com/lzugis/
在线教程
http://edu.csdn.Net/course/detail/799
Github
https://github.com/lzugis/
联系方式

类型 内容
qq 1004740957
公众号 lzugis15
e-mail [email protected]
webgis群 1004740957
Android群 337469080
GIS数据可视化群 458292378

LZUGIS

你可能感兴趣的:(GIS加油站)