如何"d3.translateExtent"协调工作? [英] How "d3.translateExtent" coordinate works?

查看:119
本文介绍了如何"d3.translateExtent"协调工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

jsfiddle演示

jsfiddle DEMO

我正在尝试向圆上添加拖动,并尝试应用translateExtent.那么如何将拖动边界限制为矩形呢??

I am trying to add a drag to the circle and trying to apply a translateExtent. So how to restrict the drag boundary to the rectangle .?

var height = 500;
var width = 500;


//if extent is specified, sets the translate extent to the specified array of points [[x0, y0], [x1, y1]], where [x0, y0] is the top-left corner of the world and [x1, y1] is the bottom-right corner of the world, and returns this zoom behavior. 
var zoom = d3.zoom()
   .translateExtent([[100, 100], [400, 400]])
    .on("zoom", zoomed);

    // Feel free to change or delete any of the code you see in this editor!
    var svg = d3.select("body")
        .append("svg")
        .attr("width", height)
        .attr("height", width)
        .append("g")

svg.append("rect")
        .attr("x", 100)
        .attr("y", 100)
        .attr("height", 300)
        .attr("width", 300);

    var circle = svg.append("circle")
        .attr("cx", 100)
        .attr("cy", 100)
        .attr("r", 20)
        .style("fill", "red")

    svg.call(zoom);

    function zoomed() {
      circle.attr("transform", d3.event.transform);
    }

有关 https://github.com/d3/d3-zoom如何进行的任何详细说明#zoom_translateExtent 有效吗?如何从坐标计算边界.

Any detailed explanation of how the https://github.com/d3/d3-zoom#zoom_translateExtent works ? How is the boundary calculated from the coordinates.

推荐答案

这里有一些注意事项,并且鉴于我过去肯定被他们绊倒了,希望我能在这里清楚地解释它们.

There are a few considerations here, and given I've certainly been tripped up by them in the past, I hope I can explain them clearly here.

缩放范围

让我们看一下缩放范围(zoom.extent)-不翻译范围.默认范围是"[[0, 0], [width, height]],其中width是元素的客户端宽度,而height是其客户端高度"(

Let's look at zoom extent (zoom.extent) - not translate extent. The default extent is "[[0, 0], [width, height]] where width is the client width of the element and height is its client height" (d3-zoom docs). Since you are calling the zoom on the svg, the default extent should be [0,0],[width,height], where width and height in your case are 500 each.

您的翻译范围[100,100],[400,400]比缩放范围,这对Mike Bostock来说是无效的:问题在于,您指定的translateExtent是小于缩放范围.因此无法满足要求的约束." ( d3-zoom问题跟踪器).

Your translate extent, [100,100],[400,400] is smaller than your zoom extent, this doesn't work, from Mike Bostock on a similar issue : "The problem is that the translateExtent you’ve specified is smaller than the zoom extent. So there’s no way to satisfy the requested constraint." (d3-zoom issue tracker).

TranslateExtent

然后的问题是,您使用的翻译范围不正确.您指定的平移范围是希望圆约束的范围.但这不等于平移范围,平移范围是在缩放范围内要显示的坐标空间的边界(圆所处的世界的边界).

The issue then, is that you are using translate extent incorrectly. The translate extent you have specified is the bounds that you want the circle to constrained to. But this is not equal to the translate extent, which is the bounds of the coordinate space you want to show (the bounds of the world in which the circle resides) given a zoom extent.

让我们考虑在[100,100]处的圆,它以translate(0,0)的缩放变换居中于该圆:位于其起始位置.这标记了希望将圆限制在其中的边界框的左上位置.此时缩放的左上坐标为[0,0].缩放范围或视口的右下角是[500,500].

Let's consider the circle at [100,100], it is centered there with a zoom transfrom with translate(0,0): it is at its starting position. This marks the top left position for the bounding box that you hope to constrain the circle in. The top left coordinate of the zoom at this point is [0,0]. The bottom right of the zoom extent or viewport is [500,500].

如果圆位于目标运动的右下角[400,400],则它的变换为translate(300,300),因为它是右移300像素,而从其起始位置向下300像素(最初以cx/cy定位) ).给定所有内容向左和向右移动300像素,则视口或缩放范围的左上角现在为[-300,-300](如果cx,cy为-300,则在缩放后,圆心将位于SVG的左上角).右下角是[200,200].

If the circle is at [400,400], the bottom right of its intended movement, it is has a transform of translate(300,300) as it is 300 pixels right and 300 pixels down from where it started (originally positioned with cx/cy). Given everything is shifted 300 pixels down and right, the top left of the viewport or zoom extent is now [-300,-300] (a circle with cx,cy of -300 would have its center at the top left corner of the SVG given the zoom transform). And the bottom right is [200,200].

首先,当圆不能进一步向上或向左移动时,我们显示的范围为[0,0],[500,500];当圆位于右下角时,当圆圈不能进一步向下或向右移动时,我们将显示[-300,-300],[200,200]的范围.

To start, when the circle cannot move further up or left, we have a shown extent of [0,0],[500,500], and when the circle is in the bottom right, when the circle cannot move further down or right, we have a shown extent of [-300,-300],[200,200].

以极端为例,我们想要的最大范围是:[-300,-300],[500,500],这是我们要显示的世界范围,以便圆与矩形重叠.

Taking the extremes, the maximum extent we want then is: [-300,-300],[500,500], this is the extent of the world we want to show so that the circle remains overlapping with the rectangle:

var height = 500;
var width = 500;

var zoom = d3.zoom()
   .translateExtent([[-300, -300], [500, 500]])
    .on("zoom", zoomed);

var svg = d3.select("body")
        .append("svg")
        .attr("width", height)
        .attr("height", width)
        .append("g")
        
svg.append("rect")
        .attr("x", 100)
        .attr("y", 100)
        .attr("height", 300)
        .attr("width", 300);
           
    var circle = svg.append("circle")
        .attr("cx", 100)
        .attr("cy", 100)
        .attr("r", 20)
        .style("fill", "red")
        
    svg.call(zoom);
    
    function zoomed() {
      circle.attr("transform", d3.event.transform);
    }

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

可能的优化

如果我们使用的缩放范围的宽度和高度等于矩形的宽度和高度:

If we use a zoom extent with width and height equal to the width and height of the rectangle:

.extent([[0,0],[300,300]])

我们不必扩展translationExtent即可解决仍在SVG内的矩形周围的空白空间:

We don't have to extend our translateExtent to account for the empty space around the rectangle that is still within the SVG:

.translateExtent([[-300,-300],[300,300]])

var height = 500;
var width = 500;


//if extent is specified, sets the translate extent to the specified array of points [[x0, y0], [x1, y1]], where [x0, y0] is the top-left corner of the world and [x1, y1] is the bottom-right corner of the world, and returns this zoom behavior. 
var zoom = d3.zoom()
    .translateExtent([[-300,-300],[300,300]])
    .extent([[0,0],[300,300]])
    .on("zoom", zoomed);
    
    console.log(zoom.extent());
    
    // Feel free to change or delete any of the code you see in this editor!
    var svg = d3.select("body")
        .append("svg")
        .attr("width", height)
        .attr("height", width);
        
     svg.append("rect")
        .attr("x", 100)
        .attr("y", 100)
        .attr("height", 300)
        .attr("width", 300);
           
    var circle = svg.append("circle")
        .attr("cx", 100)
        .attr("cy", 100)
        .attr("r", 20)
        .style("fill", "red")
        
    svg.call(zoom);
    
    function zoomed() {
      circle.attr("transform", d3.event.transform);
    }

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

这篇关于如何"d3.translateExtent"协调工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆