问题与Programmatic Zoom v4

时间:2016-09-21 19:36:36

标签: javascript d3.js svg d3v4

我正在使用d3.js v4。我目前正在实施程序化缩放。这Panning and Zooming Tutorial给了我很大的帮助。我的缩放适用于滚轮,但我想创建缩放按钮。我知道缩放和平移的必要条件是翻译[tx, ty]和比例因子k。我正在为x-Axis使用时间刻度。通过在x轴上获取txk的像素值,然后使用这些值获取,我设法得到p1 (point 1)并缩放因子p2(point 2) ak(比例因子)。像这样:

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:

var tx = 0 - k * p1;

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

我的JSFiddle

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

我尝试过什么

我的代码

应用滚轮缩放后,我运行此功能:

 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
    }

缩放功能正常,但放大后然后手动尝试缩小我想要的正常位置。 我的手动变焦按钮功能

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 + ")");

}

1 个答案:

答案 0 :(得分:3)

我现在已经看了一会儿,我得到了排序的工作,有一件事我想不通但你可能会因为你看起来更多熟悉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不是很熟悉,但这应该可以解决你的大部分问题,希望能让你知道出了什么问题。