Проекции для разных слоев d3js - PullRequest
0 голосов
/ 03 октября 2018

Я сделал карту, которая показывает несколько кругов, и по щелчку отображаются линии.Карта накладывается на базовую карту листовки.Карта работает отлично.Вот как я спроецировал карту:

d3.csv("going.csv", function(data) {
      going = data;

    d3.json("lor_migration.geojson", function(json) {

        //Projection
        transform = d3.geo.transform({
            point: projectPoint
        });
        path = d3.geo.path().projection(transform);

        function projectPoint(x, y) {
            var point = map.latLngToLayerPoint(new L.LatLng(y, x));
                this.stream.point(point.x, point.y);
        }
        //Bind data and create one path per GeoJSON feature
        var feature = g.selectAll("path")
            .data(json.features)
            .enter()
            .append("path")
            .attr("id", function(d) {
                return d.properties.state;
            })
            .attr("d", path)
            .attr("stroke-width", 0.5)
            .attr("fill-opacity", "0.5")
            .style("stroke", "#666")
            .style("fill", "#fff");

map.on("viewreset", reset);
        reset();

        //Reset function
        function reset() {
            var bounds = path.bounds(json);
                topLeft = bounds[0],
                bottomRight = bounds[1];
            svg.attr("width", bottomRight[0] - topLeft[0])
                .attr("height", bottomRight[1] - topLeft[1])
                .style("left", topLeft[0] + "px")
                .style("top", topLeft[1] + "px");
            g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
                feature.attr("d", path);
            }

Вот как нарисованы круги на карте:

 //Create circles for net migration
        var circles = g.selectAll("circle")
            .data(json.features)
            .enter().append("circle")
            .attr("cx", function(d) {
                d.centroid = path.centroid(d);
                return d.centroid[0];
            })
            .attr("cy", function(d) {
                return d.centroid[1];
            })
            .attr("r", function(d) {  //circle size
                console.log("Value: " + value);
                var diff = d.properties.total_imm - d.properties.total_emm; 
                    return circleSize((Math.abs(diff)/Math.PI));
            })
            .attr("class", "circ")
            .attr("id", function(d) {
                return d.abbrev;
            })
            .attr("fill", function(d) { //circle color
                var diff = d.properties.total_imm - d.properties.total_emm; 
                if (diff > 0) {
                    return "#65a89d";
                } 
                else {
                    return "#a96a46";
                }
            })
            .attr("fill-opacity", "0.5")
            .attr("stroke", "#fff")
            .attr("stroke-weight", "0.5")
            .on("mouseover", function(d) {
                return toolOver(d, this);
            })
            .on("mousemove", function(d) {
                var m = d3.mouse(this);
                mx = m[0];
                my = m[1];
                return toolMove(mx, my, d);
            })
            .on("mouseout", function(d) {
                return toolOut(d, this);
            })
            .on("click", function(d) {
                clicked(d)
            });

Вот функция onclick для линий:

function clicked(selected) {
    var selname = selected.id;  
    var homex = selected.centroid[0];
    var homey = selected.centroid[1];
    g.selectAll(".goingline")
        .attr("stroke-dasharray", 0)
        .remove()
    g.selectAll(".goingline")
        .data(going)
        .enter().append("path")
        .attr("class", "goingline")
        .attr("d", function(d, i) { 
            var finalval = coming[i][selname] - going[i][selname]; 
            come = coming[i][selname];
            go  = going[i][selname];   
                try {
                    var theState = d3.select("#" + d.abbrev).datum();
                    if (!isNaN(finalval)) {
                        var startx = theState.centroid[0];
                        var starty = theState.centroid[1];
                        if (finalval > 0)  
                            return "M" + startx + "," + starty + " Q" + (startx + homex) / 2 + " " + (starty + homey) / 1.5 + " " + homex + " " + homey;
                        else 
                            return "M" + homex + "," + homey + " Q" + (startx + homex) / 2 + " " + (starty + homey) / 5 + " " + startx + " " + starty;
                    }
                }
                catch (err) {
                    console.log(err)
                    console.log('No datum found for ' + d.abbrev)
                }
        })
        .call(transition)
        .attr("stroke-width", function(d, i) {
            var finalval = coming[i][selname] - going[i][selname]; 
                return 0.75//(Math.abs(finalval));
        })
        .attr("stroke", function(d, i) {
            var finalval = coming[i][selname] - going[i][selname];
            if (finalval > 0) {
                return "#65a89d";
            }
            else {
                return "#a96a46";
            }
        })
        .attr("fill", "none")
        .attr("opacity", 0.5)
        .attr("stroke-linecap", "round")
        .on("mouseover", function(d) {
            return toolOver2(d, this);
        })
        .on("mousemove", function(d, i) {
            var m = d3.mouse(this);
            mx = m[0];
            my = m[1];
            return toolMove2(mx, my, selname, d.state, coming[i][selname], going[i][selname]);
        })
        .on("mouseout", function(d) {
            return toolOut2(d, this);
        });
}

Проблема в том, что проекция не работает для кругов и линий.Можете ли вы предложить решение.Спасибо

РЕДАКТИРОВАНИЕ:

Итак, это попытка, которую я предпринял при попытке решить проблему: все еще есть некоторые проблемыпроблема в том, что если я пытаюсь использовать эту функцию, то ничего не отображается:

    json.features.forEach(function(d) {
            d.LatLng = new L.LatLng(d.geometry.coordinates[1], 
                       d.geometry.coordinates[0]);
        });

Также я получаю сообщение об ошибке:

 TypeError: t is undefined, can't access property "lat" of it

Помогите пожалуйста

1 Ответ

0 голосов
/ 05 октября 2018

Так что я исправил круги по крайней мере.Проблема была в том, что я не возвращал правильные атрибуты.Мы должны вернуть центроиды, а не войти лат.Вот обновленная версия моей функции сброса:

  //Reset function
        function reset() {

        //Defining Bounds
        var bounds = path.bounds(json);
            topLeft = bounds[0],
            bottomRight = bounds[1];
        svg.attr("width", bottomRight[0] - topLeft[0])
            .attr("height", bottomRight[1] - topLeft[1])
            .style("left", topLeft[0] + "px")
            .style("top", topLeft[1] + "px");

        //Recalculating Projections for Json map        
        g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
            feature.attr("d", path);

        //Recalculating Projections for Circles 
        circles.attr("cx", function(d) { 
            d.centroid = path.centroid(d);
            return d.centroid[0];
        });
        circles.attr("cy", function(d) {
            return d.centroid[1];
        });
        g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
            circles.attr("d", path);
        }

Мне все еще нужно вычислить проекцию линий.Есть предложения по этому поводу?

...