1

私は d3 ライブラリを使用しており、特定の状態にズームインするためのクリック アクションを取得するだけでなく、クロロプレスの例での作業にも成功しています (詳細については、この質問を参照してください)。具体的には、状態でクリックしてズームするイベントに使用しているコードは次のとおりです。

// Since height is smaller than width, 
var baseWidth = 564;
var baseHeight = 400;

d3.selectAll('#states path')
    .on('click', function(d) {
        // getBBox() is a native SVG element method
        var bbox = this.getBBox(),
            centroid = [bbox.x + bbox.width/2, bbox.y + bbox.height/2],
            // since height is smaller than width, I scale based off of it.
            zoomScaleFactor = baseHeight / bbox.height,
            zoomX = -centroid[0],
            zoomY = -centroid[1];

        // set a transform on the parent group element
        d3.select('#states')
            .attr("transform", "scale(" + scaleFactor + ")" +
                "translate(" + zoomX + "," + zoomY + ")");
    });

ただし、クリックして状態を表示すると、変換がビューポートの中心ではなく、左上にずれてしまい、適切なスケールになっていない可能性があります。scaleFactor または zoomX/zoomY パラメータを手動で微調整すると、アイテムが完全に失われます。スケールと変換を一緒に行うと結果が大きく異なる可能性があるという概念に精通しているため、調整方法がわかりません。

他に考えられる唯一のことは、元のクロロプレス画像が 960 x 500 の画像に設定されていることです。これに対応するために。albersUSA プロジェクションを作成し、このプロジェクションで d3.geo.path を使用して、それに応じてパスを追加し続けます。

私の変換は投影の影響を受けていますか? もしそうなら、私はそれにどのように対応しますか?

4

2 に答える 2

2

さらに参考のために、

この記事では、マトリックス変換を使用してズームとパンの効果を非常に簡単に実現する方法を見つける必要があります。

抜粋:

<script type="text/ecmascript">
    <![CDATA[
      var transMatrix = [1,0,0,1,0,0];

      function init(evt)
      {
        if ( window.svgDocument == null )
        {
          svgDoc = evt.target.ownerDocument;
        }
        mapMatrix = svgDoc.getElementById("map-matrix");
        width  = evt.target.getAttributeNS(null, "width");
        height = evt.target.getAttributeNS(null, "height");
      }
    ]]>
</script>

function pan(dx, dy)
{      
  transMatrix[4] += dx;
  transMatrix[5] += dy;

  newMatrix = "matrix(" +  transMatrix.join(' ') + ")";
  mapMatrix.setAttributeNS(null, "transform", newMatrix);
}
function zoom(scale)
{
  for (var i=0; i<transMatrix.length; i++)
  {
    transMatrix[i] *= scale;
  }

  transMatrix[4] += (1-scale)*width/2;
  transMatrix[5] += (1-scale)*height/2;

  newMatrix = "matrix(" +  transMatrix.join(' ') + ")";
  mapMatrix.setAttributeNS(null, "transform", newMatrix);
}
于 2012-12-11T17:05:16.550 に答える