3

D3 の behavior.drag() をマップに適用する際に問題が発生しています。この例では、マップをドラッグするとパンが非常に速くなり、クリックしたポイントがマウスにとどまりません - http://bl.ocks.org/jczaplew/6453048

私のドラッグ動作コードは次のようになります -

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. SVG 全体を翻訳せずにパンします。マップからパンする機能 (この質問で表明された懸念 - d3.jsを使用して太平洋を中心としたメルカトル図のズームとパンニングを行い、この例で実証 - http://bl.ocks.org/d3noob/4966228 ) は、望ましくない。
  2. ユーザーがマップをクリックしてドラッグすると、クリックしたポイントがカーソルに固定されます (つまり、スペインをクリックしてドラッグすると、マップがスペインを中心に回転します)。

この問題は drag.origin() と関係があると思われますが、おそらく d3.behavior.drag() をまったく使用すべきではありませんか? どんな支援も大歓迎です!

4

1 に答える 1

4

潜在的な(少し不十分ではありますが)答えを見つけたと思います。この例 ( http://mbostock.github.io/d3/talk/20111018/azimuthal.html ) のロジックを使用して、これを作成しました - http://bl.locks.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 から別のものに微調整する必要があるようです。

誰にも別のアイデアがありますか?この機能を実現するための他のよりエレガントな方法を知りたいです。

于 2013-09-06T14:24:09.790 に答える