Javascript D3.js设置初始缩放级别

Javascript D3.js设置初始缩放级别,javascript,d3.js,zooming,Javascript,D3.js,Zooming,我设置了几个图形来缩放容器,效果非常好。但是,在初始加载时,缩放级别过于接近。是否有一种设置初始缩放级别的方法,以避免必须首先缩小?我熟悉.scale方法,但在实现它时没有任何运气。这是去的路还是我错过了什么 以下是我迄今为止关于缩放的内容: var margin = {top: 20, right: 120, bottom: 20, left: 120}, width = 50000 - margin.right - margin.left, height = 120000 -

我设置了几个图形来缩放容器,效果非常好。但是,在初始加载时,缩放级别过于接近。是否有一种设置初始缩放级别的方法,以避免必须首先缩小?我熟悉.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');

通过将初始变换和缩放行为设置为相同的值,我最终实现了这一点

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)");  

在任何人仍有问题的情况下,将此答案添加为已接受答案的附录:

让这件事变得很容易理解的是

话虽如此,我设定了三个变量:

缩放、缩放宽度和缩放高度

比例是您希望缩放的初始比例,然后

zoomWidth和zoomHeight的定义如下:

zoomWidth = (width-scale*width)/2
zoomHeight = (height-scale*height)/2
其中,width和height是vis svg元素的宽度和高度

然后将上述译文修改为:

.attr("transform", "translate("+zoomWidth+","+zoomHeight+") scale("+scale+")")
以及缩放功能:

d3.behavior.zoom().translate([zoomWidth,zoomHeight]).scale(scale)
这样做可以有效地确保在加载可视化时缩放元素并使其居中

如果这对你有帮助,请告诉我!干杯

D3v4答案 如果您在这里寻找相同的,但使用D3 v4

var zoom = d3.zoom().on("zoom", function(){
    svg.attr("transform", d3.event.transform);
});

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)");
适用于d3.js v4

这与类似,但它重用初始变换并实现缩放功能

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

查看实际操作:

我使用d3和react,对最初的缩放不起作用感到非常沮丧

我在这里尝试了这些解决方案,但没有一个奏效,取而代之的是使用初始比例因子和位置,然后根据这些比例因子和位置更新缩放功能

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选择导入事件在我的案例中不起作用。所以我不得不这么做

const getEvent = () => require('d3-selection').event;
D3JS 6答案 假设您希望初始位置和比例分别为x、y和scale

const zoom=d3.zoom; const svg=d3.selectcontainerId .appendsvg .宽度,宽度 .身高,身高 .callzoom.transform,d3.zoomIdentity.translatex,y.scalescale .callzoom.on'zoom',事件=>{ attr'transform',event.transform; } .附录 .attr'transform','translate${x},${y}scale${k}`;
.callzoom.transform、d3.zoomIdentity.translatex、y.scalescale确保在触发缩放事件时,event.transform变量会考虑平移和缩放。紧随其后的一行处理缩放,而最后一行用于在启动时仅应用一次平移和缩放。

既然您正在使用SVG变换缩放进行缩放,为什么不静态设置缩放值以提供所需的缩放级别?听起来很棒!我该怎么做?Lars,缩放值静态设置的准确程度如何?我从JSON加载了缩放级别,我正在尝试在svg加载时重新创建缩放级别。您可以发布完整的解决方案吗如果这个链接仍然有效,那就太好了。。。。感谢上帝更新了我的原始答案,以参考存档的链接。谢谢在我的例子中,zoomWidth和zoomHeight,其中offsetLeft和OffsetTop感谢HandleZoomca中的if条件,因此无法在D3V5上使用此解决方案。你知道有什么变化吗?在d3版本5中是:d3.event.transform