我用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);
});
因此,如果不进行平移或缩放并直接单击,则上述代码可以正常工作。有人能给我一些我做错的线索吗?
答案 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