5

D3 でマップをスケーリングおよび変換するためのコードがいくつかありますが、パフォーマンスは非常にひどいものです。ズームとパンを行うと、更新に 3 秒近くかかります。すべての郡の線の境界を含めて、マップは見栄えが良くなると思いましたが、6 MB 以上の場合、これがボトルネックの原因である可能性があります。変換を処理する別の方法や、マップ データを最適化する方法はありますか? D3 はこのレベルの詳細には本当に適していないのでしょうか? D3の非常に新しい。 ここに画像の説明を入力

QGISを使用してDBFからGeojsonに変換された、ここからシェープファイルを使用しています: https://www.census.gov/cgi-bin/geo/shapefiles2010/main

<!doctype html>
<html>

<head>
   <title>d3 map</title>
   <script src="http://d3js.org/d3.v3.min.js">
   </script>
</head>

<body>
   <script>
            var width = 800;
            var height = 600;

            var projection = d3.geo.mercator();
            var path = d3.geo.path().projection (projection);

            var canvas = d3.select ("body")
               .append ("svg")
               .attr ("width", width)
               .attr ("height", height)

            var zoomVar = d3.behavior.zoom()
               .translate(projection.translate())
               .scale(projection.scale())
               .scaleExtent([height, 60 * height])
               .on("zoom", onPostZoom);

            var hotbox = canvas.append("g").call(zoomVar);

            hotbox.append("rect")
               .attr("class", "background")
               .attr("width", width)
               .attr("fill", "white")
               .attr("height", height);     

            d3.json ("cali.geojson", function (data) 
            {
               hotbox.append("g")
                  .attr("id", "geometry")
                  .selectAll("path")
                  .data(data.features)
                     .enter()
                        .append("path")
                        .attr("d", path)
                        .attr("fill", "steelblue")
                        .on("click", onClick);

            })




function onClick (d) 
{
   var centroid = path.centroid(d), translate = projection.translate();

   projection.translate(
   [translate[0] - centroid[0] + width / 2,
    translate[1] - centroid[1] + height / 2 ]);

   zoomVar.translate(projection.translate());

   hotbox.selectAll("path").transition()
      .duration(700)
      .attr("d", path);

}     


function onPostZoom() 
{
  projection.translate(d3.event.translate).scale(d3.event.scale);
  hotbox.selectAll("path").attr("d", path);
}

</script>
</body>
</html>
4

2 に答える 2

10

Lars が言ったように、データを適切な解像度に単純化する必要があります。ズームインする距離に基づいて最大解像度を選択します。より小さなTopoJSON 形式topojson -sの利点も得られるため、単純化することをお勧めします。

もう 1 つの重要な点は、パンとズームだけを行っている場合に再投影を避けることです。再投影は比較的コストのかかる三角演算であり、SVG で非常に大きなパス文字列をシリアル化することも同様です。パス要素またはそれを含む G 要素に変換属性を設定するだけで、パンとズーム (移動とスケーリング) でこれを回避できます。次の例を参照してください。

プロジェクションを TopoJSON ファイルに焼き付ける、プロジェクションされたTopoJSON (別の例) の使用も検討する必要があります。これにより、クライアントはさらに高速になります。投影する必要はありません。

于 2013-07-26T19:46:40.807 に答える