2013-09-05 3 views
3

У меня возникают некоторые проблемы, связанные с поведением D3 на карте. В этом примере, увлекая результаты карты в очень быстром сковороду, и точка щелкнул не остается с мышью - http://bl.ocks.org/jczaplew/6453048Использование d3.behavior.drag() для панорамирования карты

Мой код поведение перетаскивания выглядит следующим образом -

var drag = d3.behavior.drag() 
    .origin(function() { return {x: rotate[0], y: -rotate[1]}; }) 
    .on("drag", function() { 
    rotate[0] = d3.event.x; 
    rotate[1] = -d3.event.y; 

    // Refresh the map 
    projection.rotate(rotate); 
    path = d3.geo.path().projection(projection); 
    d3.selectAll("path").attr("d", path); 
}); 

Что мне нужно:

  1. Panning без перевода всего SVG. Способность панорамирования карты (проблема, выраженная в этом вопросе - Zooming and Panning a Mercator Map centered on the Pacific using d3.js и продемонстрированная в этом примере - http://bl.ocks.org/d3noob/4966228) нежелательна.
  2. Когда пользователь нажимает и тащит карту, точка щелкнул прилипает к курсору (т.е. нажав и перетащив Испания поворачивает карту вокруг Испании)

Я подозреваю, что эта проблема имеет что-то делать с drag.origin(), но, возможно, я вообще не должен использовать d3.behavior.drag()? Любая помощь очень ценится!

ответ

3

Я думаю, что нашел потенциальный (хотя и немного неудовлетворительный) ответ. Используя логику из этого примера (http://mbostock.github.io/d3/talk/20111018/azimuthal.html), я создал это - http://bl.ocks.org/jczaplew/6457917

Ключевым битом является отслеживание положения начала перетаскивания (то есть когда пользователь нажимает). Логика для лат и долго желаемого вращения проекции вращения

старт + (начальная позиция экрана - назначения положение экрана)/4

и поведение сопротивления теперь выглядит как этот

var drag = d3.behavior.drag() 
     .on("dragstart", function() { 
      var proj = projection.rotate(); 
      m0 = [d3.event.sourceEvent.pageX, d3.event.sourceEvent.pageY]; 
      o0 = [-proj[0],-proj[1]]; 
     }) 
     .on("drag", function() { 
     if (m0) { 
      var m1 = [d3.event.sourceEvent.pageX, d3.event.sourceEvent.pageY], 
       o1 = [o0[0] + (m0[0] - m1[0])/4, o0[1] + (m1[1] - m0[1])/4]; 
      projection.rotate([-o1[0], -o1[1]]); 
     } 

     // Update the map 
     path = d3.geo.path().projection(projection); 
     d3.selectAll("path").attr("d", path); 
    }); 

Это все еще кажется довольно взломанным, и, похоже, оно не очень хорошо масштабируется. Например, изменение проекции и масштаба проекции, по-видимому, требует уточнения нормализации требуемых координат вращения от 4 до чего-то другого для достижения такой же гладкости и поведения.

У кого-нибудь есть альтернативные идеи? Мне бы хотелось увидеть другие, более элегантные способы выполнения этой функции.

Смежные вопросы