使用d3.js实现缩放或缩小

3
我用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的高度?或者还有其他缩放的可能性吗?

更新 根据马克的建议,我实现了它并制作了第二个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);                           
});

所以,不需要平移、缩放或直接点击,上述代码就可以工作。有人能给我一个提示,我做错了什么吗?

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Mark
@Mark 我已经更新了我的问题。 - Elger Mensonides
1个回答

0

好的,我弄明白了。你可以使用缩放功能进行比例和平移。一个很好的例子是缩放到边界框示例,但该示例基于没有x和y缩放函数的d3.geo。

对于具有x和y线性缩放对象的情况,您可以这样做:

.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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接