web-dev-qa-db-ja.com

D3.js初期ズームレベルを設定する

コンテナを拡大するためにいくつかのグラフを設定しましたが、うまく機能します。ただし、初期ロードでは、ズームレベルが近すぎます。最初にズームアウトする必要がないように初期ズームレベルを設定する方法はありますか?私は.scale()メソッドに精通していますが、実装する運がありません。これは行く方法ですか、それとも私が見逃しているものがありますか?

これがズームに関するこれまでのところです。

var margin = {top: 20, right: 120, bottom: 20, left: 120},
    width = 50000 - margin.right - margin.left,
    height = 120000 - margin.top - margin.bottom;

var x = d3.scale.linear()
    .domain([0, width])
    .range([0, width]);

var y = d3.scale.linear()
    .domain([0, height])
    .range([height, 0]);

var tree = d3.layout.tree()
    .size([height, width])
    .separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });

var diagonal = d3.svg.diagonal()
    .projection(function(d) { return [d.x, d.y]; });

function zoom(d) {        
  svg.attr("transform",
      "translate(" + d3.event.translate + ")"+ " scale(" + d3.event.scale + ")");
}

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    .attr("pointer-events", "all")
    .call(d3.behavior.zoom()
        .x(x)
        .y(y)
        .scaleExtent([0,8])
        .on("zoom", zoom))
        .append('g');

svg.append('rect')
    .attr('width', width*5)
    .attr('height', height)
    .attr('border-radius', '20')
    .attr('fill', 'sienna');
31
Jakub Svec

私はこれを設定することで最終的に機能させました どちらも 同じ値への初期変換とズーム動作。

var zoom = d3.behavior.zoom().translate([100,50]).scale(.5);

vis = svg.append("svg:svg")
     .attr("width", width)
     .attr("height", height)
     .call(zoom.on("zoom",zooming))
           .append("svg:g")
           .attr("transform","translate(100,50)scale(.5,.5)");  
29
Pudders

D3v4回答

同じものを探しているが、D3 v4を使用している場合は、

var zoom = d3.zoom().on("zoom", zooming);

vis = svg.append("svg:svg")
     .attr("width", width)
     .attr("height", height)
     .call(zoom) // here
     .call(zoom.transform, d3.zoomIdentity.translate(100, 50).scale(0.5))
     .append("svg:g")
     .attr("transform","translate(100,50) scale(.5,.5)");
27
davcs86

まだ問題が発生している場合に備えて、この回答を承認済みの回答の補遺として追加します。

これを本当に理解しやすくしたのは、見ること ここ

そうは言っても、3つの変数を設定しました。

scale、zoomWidth、zoomHeight

scaleは、ズームを設定する最初のスケールです。

zoomWidthとzoomHeightは次のように定義されます。

zoomWidth = (width-scale*width)/2
zoomHeight = (height-scale*height)/2

ここで、幅と高さは「vis」svg要素の幅と高さです。

上記の翻訳は、次のように修正されます。

.attr("transform", "translate("+zoomWidth+","+zoomHeight+") scale("+scale+")")

ズーム機能と同様に:

d3.behavior.zoom().translate([zoomWidth,zoomHeight]).scale(scale)

これにより、視覚化が読み込まれたときに要素がズームされ、中央に配置されます。

これがあなたに役立つかどうか私に知らせてください!乾杯。

15
deweyredman

d3.jsに適用v4

これは davcs86の回答 に似ていますが、初期変換を再利用し、ズーム機能を実装します。

// Initial transform to apply
var transform = d3.zoomIdentity.translate(200, 0).scale(1);
var zoom = d3.zoom().on("zoom", handleZoom);

var svg = d3.select("body")
  .append('svg')
  .attr('width', 800)
  .attr('height', 300)
  .style("background", "red")
  .call(zoom)                       // Adds zoom functionality
  .call(zoom.transform, transform); // Calls/inits handleZoom

var zoomable = svg
  .append("g")
  .attr("class", "zoomable")
  .attr("transform", transform);    // Applies initial transform

var circles = zoomable.append('circle')
  .attr("id", "circles")
  .attr("cx", 100)
  .attr("cy", 100)
  .attr('r', 20);

function handleZoom(){
  if (zoomable) {
    zoomable.attr("transform", d3.event.transform);
  }
};

実際に見る: jsbin link

8
hexnod

反応でd3を使用していて、最初のズームが機能しないことに非常に不満を感じていました。

私はここで解決策を試しましたが、どれもうまくいきませんでしたが、代わりに最初の倍率と位置を使用して、それらの倍率と位置に基づいてズーム機能を更新しました

_const initialScale = 3;
const initialTranslate = [
  width * (1 - initialScale) / 2,
  height * (1 - initialScale) / 2,
];

const container = svg
  .append('g')
  .attr(
    'transform',
    `translate(${initialTranslate[0]}, ${initialTranslate[1]})scale(${initialScale})`
  );
_

ズーム機能は次のようになります

_svg.call(
  zoom().on('zoom', () => {
    const transformation = getEvent().transform;
    let {x, y, k} = transformation;
    x += initialTranslate[0];
    y += initialTranslate[1];
    k *= initialScale;

    container.attr('transform', `translate(${x}, ${y})scale(${k})`);
  })
);
_

関数としてgetEvent()に気付いた場合、それは_d3-selection_からのイベントのインポートが機能していないためでした。だから私はしなければならなかった

_const getEvent = () => require('d3-selection').event;
_
0
Prasanna