web-dev-qa-db-de.com

D3.js Legt die anfängliche Zoomstufe fest

Ich habe mehrere Diagramme eingerichtet, um den Container zu vergrößern, und er funktioniert großartig. Beim ersten Laden ist die Zoomstufe jedoch viel zu nah. Gibt es eine Methode, um die anfängliche Zoomstufe einzustellen, um ein Herauszoomen zu vermeiden? Ich bin mit der .scale()-Methode vertraut, hatte aber kein Glück bei der Implementierung. Ist das der Weg zu gehen oder fehlt mir etwas?

Hier ist was ich bisher bezüglich Zoom habe:

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');
27
Jakub Svec

Ich habe es endlich mit der Einstellung zum Laufen gebracht beide die anfängliche Transformation und das Zoom-Verhalten auf denselben Wert. 

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 Antwort

Wenn Sie hier das gleiche suchen, aber mit 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)");
24
davcs86

Diese Antwort als Ergänzung zu der akzeptierten Antwort hinzufügen, falls noch Probleme auftreten:

Das, was dies wirklich verständlich machte, war das Schauen hier

Davon abgesehen setze ich drei Variablen:

skalieren, zoomWidth und zoomHeight

skalierung ist die anfängliche Skalierung, die der Zoom sein soll, und dann 

zoomWidth und zoomHeight werden wie folgt definiert:

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

wobei Breite und Höhe die Breite und Höhe des svg-Elements "vis" sind

die obige Übersetzung wird dann wie folgt geändert:

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

sowie die Zoomfunktion:

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

Dadurch wird effektiv sichergestellt, dass Ihr Element vergrößert und zentriert wird, wenn Ihre Visualisierung geladen wird.

Lass es mich wissen, wenn dir das hilft! Prost.

14
deweyredman

Gilt für d3.js v4

Dies ist ähnlich zu davcs86s Antwort , verwendet jedoch eine anfängliche Transformation und implementiert die Zoomfunktion.

// 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);
  }
};

Sehen Sie es in Aktion: jsbin link

3
hexnod

Ich benutzte d3 mit reag und war sehr frustriert, weil der anfängliche Zoom nicht funktionierte. 

Ich habe die Lösungen hier ausprobiert und keine von ihnen hat funktioniert. Stattdessen nutzten sie einen anfänglichen Skalierungsfaktor und Positionen und anschließend die Zoomfunktion auf der Grundlage dieser Skalierungsfaktoren und Positionen

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})`
  );

Die Zoom-Funktion würde ungefähr so ​​aussehen

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})`);
  })
);

Wenn Sie getEvent() als Funktion erkannt haben, lag dies daran, dass das Importieren von Ereignissen aus d3-selection in meinem Fall nicht funktioniert hat. Also musste ich tun

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