首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >问题w/可编程缩放v4

问题w/可编程缩放v4
EN

Stack Overflow用户
提问于 2016-09-21 19:36:35
回答 1查看 858关注 0票数 5

我在用d3.js v4。我目前正在实现编程缩放。这个Panning and Zooming Tutorial提供了巨大的帮助。我的缩放工作与滚动轮,但我想创建按钮缩放。我知道缩放和平移所必需的是一个翻译[tx, ty]和一个缩放因子k。我的x轴是用时间刻度的。我得到了txk的缩放因子,方法是在x轴上得到p1 (point 1)p2(point 2)的像素值,然后使用这些值得到k(缩放因子)。像这样:

代码语言:javascript
复制
var k = 500 / (xScale(p2) - xScale(p1)); //500 is desired pixel diff. between p1 and p2, and xScale is my d3.scaleTime() accessor function.
// for this zoom i just want the first value and last value to be at scale difference of the entire width.

然后我用这个计算tx:

代码语言:javascript
复制
var tx = 0 - k * p1;

然后将其输入到一个d3.zoomIdentity()中,并重新调整我的x域。我创建了一个按钮来放大。问题是,当我放大,然后尝试使用按钮放大,它放大,但缩小x轴。我似乎找不出为什么它缩小了x轴,而不是正确地缩小了。

My JSFiddle

https://jsfiddle.net/codekhalifah/Lmdfrho7/2/

我试过什么

我的代码

应用滚轮变焦后,我运行以下功能:

代码语言:javascript
复制
 function zoomed() {
        if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return; // ignore zoom-by-brush  
var t = d3.event.transform;
console.log(t);
console.log(xScale.domain());
xScale.domain(t.rescaleX(x2).domain());
usageAreaPath.attr("d", area);
usageLinePath.attr('d',line);
weatherAreaPath.attr('d',weatherChart.area);
focus.select(".axis--x").call(xAxis);
focus.selectAll('.circle')
    .attr('cx', function(d) { return xScale(getDate(d)); })
    .attr('cy', function(d) { return yScale(d.kWh); })
    .attr("transform", "translate(0," + 80 + ")");

        ... other non related items
    }

变焦工作正常,但在放大后,然后手动试图放大回到我想要的正常位置。我的手动缩放按钮功能

代码语言:javascript
复制
function programmaticZoom(){
 var currDataSet = usageLinePath.data()[0], //current data set
        currDataSetLength = currDataSet.length,//current data set length
        x1 = currDataSet[0].usageTime, //getting first data item
        x2 = currDataSet[currDataSetLength-1].usageTime, //2nd data item
        x1px = xScale(moment(x1)), //Get current point 1
        x2px = xScale(moment(x2)); // Get current point 2

        // calculate scale factor
        var k = width / (x2px - x1px); // get scale factor
        var tx = 0 - k * x1px; // get tx
        var t = d3.zoomIdentity.translate(tx).scale(k); //create zoom identity

        xScale.domain(t.rescaleX(window.x2).domain());
        usageAreaPath.attr("d", area);
        usageLinePath.attr('d',line);
        weatherAreaPath.attr('d',weatherChart.area);
        focus.select(".axis--x").call(xAxis);
        focus.selectAll('.circle')
            .attr('cx', function(d) { return xScale(getDate(d)); })
            .attr('cy', function(d) { return yScale(d.kWh); })
            .attr("transform", "translate(0," + 80 + ")");

}
EN

回答 1

Stack Overflow用户

发布于 2016-09-30 14:26:54

我已经看了很长一段时间了,我开始有点工作了,有一件事我搞不懂,但你也许能理解,因为你看起来比我更熟悉d3在您的programmaticZoom()函数中,我注意到tx是图开始位置的偏移量,k是标度。使用这个,我更改了块:

var k = width / (x2px - x1px); // get scale var tx = 0 - k * x1px; // get tx var t = d3.zoomIdentity.translate(tx).scale(k);

var k = 1; var t = d3.zoomIdentity.scale(k);

首先,当k = 1.0时,图形将非常适合于窗口。我认为将k设置为以前值的原因是错误的,因为当您将k的值增加到k > 1.0时,它会将图形的宽度扩展到屏幕上。图形上的内容必须重新调整,这样它才能在图形上占据尽可能多的空间,同时仍然在屏幕的范围内。对于k < 1,这就是width / (x2px - x1px);发生的情况,图形缩小到小于屏幕的大小。这样的调整只会使图形的内容适合于在图形中占据它所能达到的最大值,但是由于图形比屏幕小,它将被重新调整以适应缩小的图形,并且看起来比屏幕小。

我完全摆脱了tx,因为它抵消了图形开始的位置。当图形被放大时,它的宽度会延伸到屏幕上。在这里进行偏移是有意义的,因为您需要让您的偏移量等于您想要开始查看图形的位置,并且允许不需要保留在屏幕上的部分。在你一路放大的情况下,图形就是屏幕的大小,所以偏移会导致你的图形不从屏幕的开头开始,而是把它的一部分从屏幕上推开。在您的例子中,由于k已经缩小了图形,偏移量会导致缩小的图形出现在屏幕的中间。但是,如果图形没有缩小,偏移量会将部分图形从屏幕上推开。

通过改变这一点,缩放按钮似乎工作,但仍然存在一个问题。在zoomed()函数中,设置var t = d3.event.transform;d3.event.transform包含k, x, and y的值,这些值在完全放大后分别需要为1, 0, and 0。不过,我不能在programmaticZoom()函数中更改这些值,因为只有在触发事件(特别是鼠标轮)之后才存在d3.event.transform。如果只有单击缩放按钮时才能使这些值成为k = 1, x = 0, y = 0,则问题应该完全修复。

希望这对一些人有所帮助,我不太熟悉d3,但这应该可以解决大部分问题,并希望能给您一个错误的想法。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39625154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档