使用d3.js缩放或缩放

时间:2015-07-01 13:15:10

标签: d3.js

我用d3创建了一个图表来显示表面上的缺陷。表面本身宽约1000毫米,但可能长达几公里。为了更清楚地看到缺陷,我已经实现了d3缩放,但是,有时缺陷会在x范围内扩散,因此放大那么远将导致必须从左向右滚动。

这是一个简化的jsFiddle

然而,我可以改变比例来查看特定缺陷,比如一个从1000毫米开始到1500毫米我可以做到:

var yScale = d3.scale.linear() 
     .domain([1000 - margin, 1500 + margin])
     .range([0, pixelHeight]);   

但由于我的缺陷是矩形,我需要用yScale计算宽度,如下所示:

.attr("height", function (d) {
        return yScale(d.height);
    })

如果我更改了比例的域,那么这将不起作用(高度可能小于域值,给出负值)。

那么我该如何解决这个问题呢?有没有办法计算缺陷相对于yScale的高度。或者还有另一种缩放可能性吗?

更新 根据Marks的建议,我实施了它,并制作了第二个jsFiddle

我现在面临的问题还在于尺度。我试图修改它但是只要使用平移或缩放,缩放函数(xScale和yScale)就不会给出正确的值(大多数是负的,因为它超出了视口)。

.on('click', function (d) {
    d3.selectAll('rect').classed('selected-rect', false);
    d3.select(this).classed('selected-rect', true);

    var dx = xScale(d.width)*2.2,
        dy = yScale(d.height)*2.2,
        x = xScale(d.x) ,
        y = yScale(d.y) ,
        scale = .9 / Math.max(dx / width, dy / pixelHeight),
      translate = [pixelWidth / 2 - (scale*1.033) * x, 
                   pixelHeight / 2 - (scale*1.033) * y];

    svg.transition()
        .duration(750)
        .call(zoom.translate(translate).scale(scale).event);                           
});

因此,如果不进行平移或缩放并直接单击,则上述代码可以正常工作。有人能给我一些我做错的线索吗?

1 个答案:

答案 0 :(得分:0)

好的,我想通了。您可以使用缩放功能进行缩放和平移。一个很好的例子是zoom to bounding box example,但是这个例子是基于没有x和y缩放函数的d3.geo。

使用x和y lineair缩放对象,你可以这样做:

.on('click', function (d) {
    d3.selectAll('rect').classed('selected-rect', false);
    d3.select(this).classed('selected-rect', true);

    zoom.translate([0, 0]).scale(1).event;   

    var dx = xScale(d.width),
        dy = yScale(d.height),
        x = xScale(d.x) + xScale(d.width/2),
        y = yScale(d.y) + yScale(d.height/2),
        scale = .85 / Math.max(dx / pixelWidth, dy / pixelHeight),
      translate = [pixelWidth / 2 - scale * x, 
                   pixelHeight / 2 - scale * y];

    svg.transition()
        .duration(750)
        .call(zoom.translate(translate).scale(scale).event);                           
});

首先:在进行任何xScale和yScale计算之前,您必须重置平移和缩放。我只是通过这个声明来做到这一点:

zoom.translate([0, 0]).scale(1).event; 

dx和dy是对象的缩放宽度/高度。要到达对象的中间,需要获取缩放的x和y值,并为其添加一半的宽度和高度。否则它就不能正确地居中(我说现在因为我一直在摆弄它)。

通过获取对象的最大宽度或高度来计算比例,并且将其除以0.85以得到它周围的一点边距。

这是jsFiddle