D3を使用して、外部からロードされたSVGにパスのバウンディングボックスをにズーム

lexiexiexi:

私は(マップを手伝統的なマップを作成し、非されたとして)topojsonを使用していない外部のSVGマップをロードするためにD3を使用しています。私は、要素をターゲットにしようとしている#lines pathクリックしたときになるように、各パスのズームとそのバウンディングボックスを埋めます。

私が使用しようとしている。この例のマイク・ボストックからではなく、topojsonを使用していないデータでそれを複製する方法を見つけ出すことはできません。この行を参照してください。

.data(topojson.feature(us, us.objects.states).features)

また、このことも可能?

ここで私はSVGをロードするために使用しているコードがあります。

var mapContainer = $('.map');

d3.xml("../assets/subwaymap.svg", function(error, subwayMap) {
  if (error) throw error;
  $('.map').append(subwayMap.documentElement)

私が使用してバウンディングボックスを取得しようとしました.getBBOXが、それはどのように接続するかで混乱しています。それは私が使用することを見てきたすべての例のように思えるd3.create("svg")し、その内のすべての機能をタックが、私のデータは既にDOMに追加されているので、これは必要でしょうか?D3にかなり新しいです。ありがとう!

ヘラルド・ファータド:

2つの初期の考慮は:d3.create("svg")めったに本当のD3コードで使用されていません。(あなたが呼んでいる場合を除き、そのまた、あなたが読み込まれ、DOM、ちょうどSVG要素に追加されたデータを持っていない「データ」)。

戻るあなたの質問に、あなたは必要ありません。path.bounds実際に、あなたも必要としない、あなたのコードを動作させるためにd3.zoom必要なのは(と要素のボックスを取得しているgetBBox)と、適切な変換を行います。

本当の問題は、しかし、あなたは内のすべての要素をラップする必要があるということです<g>あなたはSVG 1.1のルートSVG(どうやらこれはSVG 2で可能である)に変換を適用することはできませんので、。

ここでは基本的なデモがあります。このデモでは、私はあなたがしている添付SVGを表し異なる要素(円、長方形、テキスト...)で作られた外部SVGを使用しています。あなたは、このSVGとを取得します:

const svg = d3.select("svg");

次に、あなたが何らかの形で修正するために管理考える<g>私が言及した問題を、あなたはそのグループを取得します...

const g = svg.select("g");

...そしてあなたは(ここでは、すべてのもの)に拡大したい要素を選択し、イベントリスナーをバインド:

const elements = g.selectAll("*")
    .on("click", clicked);

このデモでは、私は(私の)時間を節約するために、ボストックの数学を使用していますが、あなたはそれを変更することができます。、ズームイン、ズームアウトするには、再度それをクリックする要素をクリックします。

const width = 500,
  height = 400;
const svg = d3.select("svg");
const g = svg.select("g");
const elements = g.selectAll("*")
  .each(function() {
    d3.select(this).datum({})
  })
  .on("click", clicked);

function clicked(d) {
  d.clicked = !d.clicked;
  const bounds = this.getBBox();
  const x0 = bounds.x;
  const x1 = bounds.x + bounds.width;
  const y0 = bounds.y;
  const y1 = bounds.y + bounds.height;
  g.transition().duration(1000).attr("transform", d.clicked ? "translate(" + (width / 2) + "," + (height / 2) + ") scale(" + (1 / Math.max((x1 - x0) / width, (y1 - y0) / height)) + ") translate(" + (-(x0 + x1) / 2) + "," + (-(y0 + y1) / 2) + ")" : "transform(0,0) scale(1)");
}
<svg width="500" height="400">
<g>
<circle cx="50" cy="50" r="30" stroke="black" stroke-width="3" fill="teal"></circle>
<rect x="300" y="20" rx="20" ry="20" width="150" height="150" style="fill:tomato;stroke:black;stroke-width:3"/>
<polygon points="200,100 250,190 160,210" style="fill:lavender;stroke:purple;stroke-width:3" />
<path d="M 140 350 q 150 -200 350 0" stroke="blue" stroke-width="5" fill="none" />
<text x="30" y="300" transform="rotate(-30, 30, 300)">Foo Bar Baz</text>
</g>
</svg>
<script src="https://d3js.org/d3.v5.min.js"></script>

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=14307&siteId=1