在D3js中绘制正交图上的选择性数据点

时间:2017-03-22 06:22:42

标签: d3.js

所以我正在使用d3js V4制作可拖动的正交地图。我需要在地图上绘制大量的点。但是绘制所有这些都会减缓拖延速度。我在想是否可以获得可见坐标的点并在拖动时再次获取点。

所以基本上,我想获得在视口中可见的最大和最小lat-lon对,根据这些对获取并绘制我的数据点。一旦我拖动地球,我再次获得这些新对并获取并在地图上绘制新点。

我尝试使用getBBox并转换x& y使用projection.invert将值转换为lat-lon对,然后根据这些点获取我的数据点,但x& y值它的给定似乎不正确(我的svg元素有一个动态的高度和宽度,但getBBox给出的高度和宽度为600px,我假设getBBox会给我svg的x& y值。我理解这个错误吗?)

以下是目前的代码。

    var height=window.innerHeight*.8, width=(window.innerWidth<768)?500:window.innerWidth*0.7, sens = 0.25, scaleValue=window.innerWidth<768?150:300;
    var dataList={};

    var projection = d3.geoOrthographic()
                .scale(scaleValue)
                .translate([width/2,height/2]);
    var graticule = d3.geoGraticule();
    var svgPath = d3.geoPath().projection(projection).pointRadius( function(d,i) {
        return 1;
    });

    /*drag globe to view more*/
    var dragged = d3.drag()
        .subject(function() { 
            var pointOfDrag = projection.rotate(); 
            return {x: pointOfDrag[0] / sens, y: -pointOfDrag[1] / sens}; 
        })
        .on("drag", function() {
            var rotate = projection.rotate();
            projection.rotate([d3.event.x * sens, -d3.event.y * sens, rotate[2]]);
            //console.log(projection.invert([d3.event.x * sens, -d3.event.y * sens]));
            svg.selectAll("path.land").attr("d", svgPath);
            svg.selectAll("path.graticule").attr("d", svgPath);


            var bbox = svg.node().getBBox();
            var x1 = bbox.x;
            var y1 = bbox.y;
            var x2 = bbox.x+bbox.width;
            var y2 = bbox.y+bbox.height;

            var lonLat1 = projection.invert([x1, y1]);
            var lonLat2 = projection.invert([x2, y2]);
            getDataPoints(lonLat1, lonLat2);
            locations.selectAll("path.geo-node").attr("d", svgPath);
        });

    var svg=d3.select("body").append("svg").attr("height",height).attr("width",width).call(dragged);
    var locations = svg.append('svg:g')
        .attr('id', 'locations');

    svg.append("path")
        .datum(graticule)
        .attr("class", "graticule")
        .attr("d", svgPath);

    var mapData={}, dataPoints={};

    $.when( $.ajax( "/world" )).done(function ( v1) {
        drawGlobe(v1);
    });

    var drawGlobe = function(map){
        svg.selectAll("path.land")
            .data(topojson.feature(map, map.objects.countries).features)
            .enter().append("path")
            .attr("class", "land")
            .attr("d", svgPath);

        svg.insert("path", ".graticule")
            .datum(topojson.feature(map, map.objects.countries).features)
            .attr("class", "land")
            .attr("d", svgPath);
        var bbox = svg.node().getBBox();
        var x1 = bbox.x;
        var y1 = bbox.y;
        var x2 = bbox.x+bbox.width;
        var y2 = bbox.y+bbox.height;
        var lonLat1 = projection.invert([x1, y1]);
        var lonLat2 = projection.invert([x2, y2]);
        getDataPoints(lonLat1, lonLat2);
    };
    var drawPoints=function(dataList){
        var circles = locations.selectAll('path')
            .data(dataList)
            .enter()
            .append('svg:path')
            .datum(function(d) {
               return {type: "Point", coordinates: [d.coord["Lon"], d.coord["Lat"]]};
            })
            .attr('class', 'geo-node')
            .attr('d', svgPath);
    }

任何人都可以指导我正确的方向吗?

修改

添加了plunker较小的数据集

0 个答案:

没有答案