1

ボタンで起動する d3 ズーム ツアーで、米国北東部の 3 つのポイントを通過しようとしていますが、データを視覚的に表示するのに苦労しています (ただし、コンソールには表示されます)。私は初心者で、通常は問題を解決できますが、これは私の頭の中にあります。

私がやろうとしていることに近い例を次に示します。

米国内のさまざまなスポットをズーム: http://bl.ocks.org/mbostock/6242308

この例では、データのスタイルを設定せず、TopoJSON を使用し、キャンバスを使用してズーム呼び出しを行います。GeoJSON を使用してズームを実行しようとしています (CartoDB テーブルにリンクできるようにするため)、スタイルを設定します。

私はこれらの両方を実現するために多くのことを経験してきましたが、成功はほとんどありません。現在、それは空白になり、されています。データをライブで見ることができますが、スタイルを変更できません。

ここで何が間違っていますか?簡単なことだと思いますが、ちょっとしたコツが必要です。


<!DOCTYPE html>
<html lang ="en">
<head>
  <meta charset="utf-8">
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style type="text/css">
canvas{
color: 'blue';

}
    path.state {
      color: 'red';
    }
    </style>
</head>
<body>

<script type="text/javascript">

var width = 960,
    height = 500,
    stateMap; 

var sf = [-122.417, 37.775],
    ny = [-74.0064, 40.7142];

var scale,
    translate,
    visibleArea, // minimum area threshold for points inside viewport
    invisibleArea; // minimum area threshold for points outside viewport

var zoom = d3.behavior.zoom()
    .size([width, height])
    .on("zoom", zoomed);

var projection = d3.geo.mercator()
    .translate([width/2, height/2])
    .scale(500);

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

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

var context = canvas.node().getContext("2d");

var path = d3.geo.path()
    .projection(simplify)
    .context(context);

stateMap = d3.json("http://linepointpath.cartodb.com/api/v2/sql?format=GeoJSON&q=SELECT * FROM GRAPHstates", function(error, stateMap) {
  console.log(stateMap)
  canvas
      svg.selectAll("path")
      .data(stateMap.feature)
      .enter().append("path")
      .attr("class", "state")
           .attr("d", path)
      .call(zoomTo(sf, 4).event)
    .transition()
      .duration(60 * 1000 / 89 * 2)
      .each(jump);
});

var simplify = d3.geo.transform({
  point: function(x, y, z) {
    if (z < visibleArea) return;
    x = x * scale + translate[0];
    y = y * scale + translate[1];
    if (x >= -10 && x <= width + 10 && y >= -10 && y <= height + 10 || z >= invisibleArea)     this.stream.point(x, y);
  }
});

function zoomTo(location, scale) {
  var point = projection(location);
  return zoom
      .translate([width / 2 - point[0] * scale, height / 2 - point[1] * scale])
      .scale(scale);
}

function zoomed(d) {
  translate = zoom.translate();
  scale = zoom.scale();
  visibleArea = 1 / scale / scale;
  invisibleArea = 200 * visibleArea;
  context.clearRect(0, 0, width, height);
  context.beginPath();
  path(d);
  context.stroke();
}

function jump() {
  var t = d3.select(this);
  (function repeat() {
    t = t.transition()
   .call(zoomTo(ny, 6).event)
  .transition()
    .call(zoomTo(sf, 4).event)
    .each("end", repeat);
  })();
}

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

1 に答える 1

0

より大きな問題は、あなたが行っている例がTopoJSONを使用しているときにGeoJSONを使用していることだと思います。2 つの違いにより、のレンダリング方法に問題が発生する可能性があります。path

実行している別の問題はcanvas、関数呼び出しが異なることです。通常のsvg関数呼び出しを使用して SVG を追加し、データをバインドし、スタイルを設定します。では、キャンバスオブジェクトcanvasを介して要素を操作します。これは、コードで使用しようとしている標準の SVG オブジェクトとは異なる構文と使用法を持っています。このチュートリアルに従うと、彼女が SVG 関数をまったく呼び出さず、代わりに API を使用して要素を描画およびスタイル設定していることに気付くでしょう。コードの実際の例を必ず見てください。contextcontextcanvas

あなたの場合、これはあなたのコードを意味します:

svg.selectAll("path")
  .data(stateMap.feature)
  .enter().append("path")
  .attr("class", "state")
       .attr("d", path)
  .call(zoomTo(sf, 4).event)
.transition()
  .duration(60 * 1000 / 89 * 2)

不要であり、何もしません。パスを生成するコードは、オブジェクトzoomed()を使用して関数に埋め込まれています。context

context.clearRect(0, 0, width, height);
context.beginPath();
path(d);
context.stroke();

関数を使用して、context表示しようとしているオブジェクトを作成しています。この動作を生成する関数呼び出しのチェーンがあり、チェーンを分解して、各ステップで必要なものを取得していることを確認する必要があります。

GeoJSON を使用する場合は、マップを表示してからズーム機能を適用することから始めます。必要なビジュアライゼーションを繰り返し構築することで、最終的には作業が大幅に楽になるでしょう。

canvassvgD3の違いの詳細については、それぞれで同じ操作を行う例を含めて、このブログ投稿をチェックして、プロジェクトを頑張ってください。

于 2014-12-30T15:01:42.417 に答える