2015-05-27 6 views
1

Я пытаюсь исказить карту d3.geo.path() с помощью плагина fisheye.js (https://github.com/d3/d3-plugins/tree/master/fisheye).d3.js fisheye distortion на карте

Для искажения объекта плагин нуждается в x & y атрибутах.

В d3.js вики он говорит:

Функция проекции принимает два элемента массива чисел, представляющих координаты местоположения, [долгота, широта] а, и возвращает подобное двухэлементной массив чисел, представляющий проецируемую позицию пикселя [x, y]. Например, элементарная сферическая проекция Меркатора:

https://github.com/mbostock/d3/wiki/Geo-Paths

Таким образом, искажение должно быть возможно, я просто не могу обернуть мою голову вокруг него.

Я использую мир-50m.json для своей проекции. После загрузки имеется массив дуг. Я думаю, что это координаты, которые мне нужно манипулировать. Но это догадка ...

Спасибо,

Ким

ответ

2

Я нашел ваш пост ищет ответ, и он не появляется, чтобы быть там на интернетах. Но, как вы говорите, это возможно!

Следуя документации от fisheye.js (https://github.com/d3/d3-plugins/tree/master/fisheye), в обратном вызове mousemove вам необходимо использовать рыбий глаз по координатам.

Поскольку Рыбий использует атрибуты .x и .y, я изменил код сверхширокоугольный просто использовать две пары [x,y], чтобы избежать, что промежуточной структуры данных каждый раз, когда в функции обратного вызова.

Тогда вы можете сделать это следующим образом:

canvas.on("mousemove", function() { 
    // console.log("mouse:"); 
    // console.log(d3.mouse(this)); 
    var here = d3.mouse(this); 
    // console.log(here); // [1030, 125] 
    // console.log(projection.invert(here)); // [-72.4713375653601, 45.14035261565636] 
    var inverted = projection.invert([here[0],here[1]]); // [-72.4713375653601, 45.14035261565636] 
    // console.log(inverted); // [-72.4713375653601, 45.14035261565636] 
    // burlington is lat 44, lon -73 
    fisheye.focus(inverted); 

    // of course, the path function takes [longitude, latitude], so -72, 44 for burlington 
    // https://github.com/mbostock/d3/wiki/Geo-Paths 
    // (so that's what it gives back) 

    states.attr("d",null) 
     .attr("d", function(d) { 
      // console.log("original:"); 
      // console.log(d.geometry); 

      if (d.geometry.type === "Polygon") { 
       var b = d.geometry.coordinates.map(function(d) { return d.map(function(f) { return fisheye(f);}); }); 
      } 
      else { 
       var b = d.geometry.coordinates.map(function(d) { return d.map(function(f) { return f.map(function(g) { return fisheye(g); }); }); }); 
      } 
      // console.log(b); 
      var c = {type: d.geometry.type, coordinates: b}; 

      // console.log("new:"); 
      // console.log(c); 

      return path(c); 
    }); 

Вы можете посмотреть концертную версию здесь: http://panometer.org/instruments/teletherms/?window=25&var=maxT&year=1914&city=BURLINGTON%20WSO%20AP,%20VT

+0

Привет Энди, вы не могли бы объяснить последовательность '' d.map' и ф. map' в разделе if/else? Что именно они делают, и почему вы использовали 'd.map' в первом, а затем' d.map' и 'f.map' во втором? Я пытаюсь реализовать искажение рыбий глаз подобным образом, но у меня есть некоторые проблемы с моей головой вокруг этого, и, следовательно, возникают ошибки (все пути заканчиваются обращением к NaN). Спасибо! – scrollex

+0

Извинения за короткий ответ. Поэтому переменные JS являются функциональными. Я бы рекомендовал прочитать «JS: хорошие детали» (Crawford) для хорошей справки JS (я получил довольно далеко в D3 без особого JS, но он догоняет). –