D3 и листовка, возвращающая разные SVG в Chrome/Safari и Firefox.

StackOverflow https://stackoverflow.com//questions/23017770

  •  21-12-2019
  •  | 
  •  

Вопрос

я следую этот пример создания карты с листовкой и d3, используя последние версии d3 и листовки.Что-то в моем коде заставляет d3 возвращать разные значения для элементов SVG в Chrome и FF 28.Это приводит к перекосу точек в FF, который имеет разные значения d в элементах PATH, а также разные свойства преобразования в элементах SVG.

Вот SVG для Chrome:

<svg width="1049711" height="1802" transform="translate(127,1079)" style="margin-left: -127px; margin-top: -1079px;">
<g class="leaflet-zoom-hide" transform="translate(127,1079)">
<path class="nora f" id="1383_ST_BERNARD_AVE" lat="29.970905251" long="90.064206456" d="M287,210m0,2a2,2 0 1,1 0,-4a2,2 0 1,1 0,4z"></path>
<path class="fixed f" id="7400_ADVENTURE_AVE" lat="30.0599104550001" long="89.9260116889999" d="M1092,-389m0,2a2,2 0 1,1 0,-4a2,2 0 1,1 0,4z"></path>

Вот SVG для Firefox

<svg width="1049711" height="1802" style="margin-left: -97px; margin-top: -1079px;" transform="translate(97,1079)">
<g class="leaflet-zoom-hide" transform="translate(97,1079)">
<path class="nora f" id="1383_ST_BERNARD_AVE" lat="29.970905251" long="90.064206456" d="M317,210m0,2a2,2 0 1,1 0,-4a2,2 0 1,1 0,4z"/>
<path class="fixed f" id="7400_ADVENTURE_AVE" lat="30.0599104550001" long="89.9260116889999" d="M1122,-389m0,2a2,2 0 1,1 0,-4a2,2 0 1,1 0,4z"/><path class="nora f" id="4170_OLD_GENTILLY_RD" lat="30.0024662600001" long="90.0401487569999" d="M457,-3m0,2a2,2 0 1,1 0,-4a2,2 0 1,1 0,4z"/>

Вот код, который загружает карту и проецирует точки.В самом конце есть функция project который возвращает другое значение x для точки в Chrome и FF 28.Я думаю, что эта строка создает общую проблему с кодом.Значение x в разное время отличается на разные значения, поэтому внести поправку сложно.

    var map = new L.Map("map", {center: [29.95, -90.05], zoom: 13, minZoom:10, maxZoom:18})
        .addLayer(new L.tileLayer('http://{s}.www.toolserver.org/tiles/bw-mapnik/{z}/{x}/{y}.png'));

    var svg = d3.select(map.getPanes().overlayPane).append("svg"),
       g = svg.append("g").attr("class", "leaflet-zoom-hide");

    //these brackets are jinja2 template syntax. They eventually return 'static/out.json' 
    d3.json('out.json') }}', function(collection) {
     var bounds = d3.geo.bounds(collection),
      path = d3.geo.path().projection(project).pointRadius(function (d) {return 2});
    console.warn(path)

     var feature = g.selectAll("path")
      .data(collection.features)
    .enter().append("path").attr("class", function(d){
      return d.properties.category + " " + d.properties.investigates;;
    }).attr("id", function(d){
      return d.geometry.address;
    }).attr("lat", function(d){
       return Math.abs(d.geometry.coordinates[1]);
    }).attr("long", function(d){
       return Math.abs(d.geometry.coordinates[0]);
    });
    $(".t").on("click", function(e) {

        var adr = "/" + this.id;
        showDialog(adr);
    });

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


      // Reposition the SVG to cover the features.
      function reset() {
        console.warn(bounds)
        var bottomLeft = project(bounds[0]),
            topRight = project(bounds[1]);


    svg .attr("width", topRight[0] - bottomLeft[0])
        .attr("height", bottomLeft[1] - topRight[1])
        .style("margin-left", bottomLeft[0] + "px")
        .style("margin-top", topRight[1] + "px").attr("transform", "translate(" + -bottomLeft[0] + "," + -topRight[1] + ")");

     g .attr("transform", "translate(" + -bottomLeft[0] + "," + -topRight[1] + ")");

    feature.attr("d", path)
  }

      // Use Leaflet to implement a D3 geographic projection.
      function project(x) {
        var point = map.latLngToLayerPoint(new L.LatLng(x[1], x[0]));
        return [point.x, point.y];
      }          
      });

я предложил это как ошибку к листовке.Если вы попробуете скрипт в FF 28 и Chrome, вы увидите, что строка 51 возвращает разные значения x для одной и той же широты/долготы в Chrome (правильное значение x) и Firefox (неверное значение x).

Я пробовал эту скрипту в FF 27 и FF 28 - каждая из этих версий Firefox возвращает другое (и неправильное) значение x для точки в строке 51.

Я обнаружил ошибку в листовке или d3 или возникла проблема с моим кодом?Есть ли обходной путь?Что тут происходит?

Это было полезно?

Решение

В итоге я заставил это работать, следуя этому примеру: https://gist.github.com/ZJONSSON/2957559

Вот рабочий код:

var path = d3.geo.path().projection(function project(x) {
    var point = map.latLngToLayerPoint(new L.LatLng(x[1], x[0]));
    return [point.x, point.y];
}).pointRadius(function(d) {
    return 2;
});

/* Load and project/redraw on zoom */
d3.json("static/out.json", function(collection) {
    var feature = g.selectAll("path")
        .data(collection.features)
        .enter().append("path")
        .attr("class", function(d) {
            return d.properties.category + " " + d.properties.investigates + " " + d.properties.thumbnail;
        }).attr("id", function(d) {
            return d.properties.address;
        }).attr("lat", function(d) {
            return Math.abs(d.geometry.coordinates[1]);
        }).attr("long", function(d) {
            return Math.abs(d.geometry.coordinates[0]);
        })
        .attr("d", path);

    map.on("viewreset", function reset() {
        feature.attr("d", path);
    });
    loadThumbs();
});

Другие советы

Проблема в том, как вы звоните d3.json.

d3.json('{{url_for('static', filename='out.json') }}', //...

недействителен.А d3.json функция ожидает, что ее первым параметром будет строка URL, а не объект.И в FF, и в webkit вы, вероятно, получаете случайный мусор, и именно его ваш код использует для вычисления границ.

Вы пытаетесь использовать шаблон (т.усы) для создания URL?Если да, то вы забываете визуализировать шаблон.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top