Abd*_*eed 5 javascript svg d3.js d3v4
我正在使用d3.js v4
.我目前正在实施程序化缩放.这种平移和缩放教程有很大帮助.我的缩放适用于滚轮,但我想创建缩放按钮.我知道缩放和平移的必要条件是翻译[tx, ty]
和比例因子k
.我正在为x-Axis使用时间刻度.我已经成功地获得tx
和比例因子k
,通过获取的像素值p1 (point 1)
,并p2(point 2)
在x轴,然后使用这些值来获得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.
Run Code Online (Sandbox Code Playgroud)
然后我用这个计算tx:
var tx = 0 - k * p1;
Run Code Online (Sandbox Code Playgroud)
然后将它喂入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
}
Run Code Online (Sandbox Code Playgroud)
缩放工作正常,但放大后然后手动尝试缩放我想要的正常位置.我的手动变焦按钮功能
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 + ")");
}
Run Code Online (Sandbox Code Playgroud)
我已经研究这个有一段时间了,我得到了它的工作原理,有一件事我无法弄清楚,但你可能能够弄清楚,因为你似乎比我更熟悉 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 不太熟悉,但这应该可以解决您的大部分问题,并希望让您了解出了什么问题。