我使用D3 v4创建了一个图表,允许x轴平移和缩放。我在平移和缩放时以不同方式更新图形,以减少重新生成图形的次数。
至于平移
当用户向左或向右平移时,我只需更新transform
属性:
path.attr("transform", d3.event.transform)
。
效果很好。
至于缩放
我重新缩放域并在用户放大时重新生成图形,以便实现所需的行为:
t = d3.event.transform;
xScale.domain(t.rescaleX(x2).domain()); //update xScale domain
xAxis =d3.axisBottom(xScale)...
focus.select(".axis--x").call(xAxis);
usageAreaPath.attr("d", area); //area being a reference to the generator
usageLinePath.attr('d',line); //line being the name of the generator
问题是,在缩放后执行平移或在平移后执行缩放会导致图形跳转到不同的缩放级别。我不确定我做错了什么,或者如何在缩放/平移后重新调整比例以更新适当的比例,但我在下面附加了一个JSBIN:
答案 0 :(得分:1)
您的代码有两个独立的问题:
<强> 1。翻译强>
您以错误的方式使用了.attr("transform", "translate( 0, 80)")
。移除.attr("transform", "translate(0," + 80 + ")")
,<path>
,轴和区域中的所有<circle>
,然后设置偏移量:
// Usage x-axis
var gX = focus.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + (height + margin.top) + ")")
.call(xAxis);
// Focus Viewpoint
var focus = svg.append("g")
.attr("class", "focus")
.attr('transform', "translate("
+ margin.left + "," + (margin.top + 80)
+ ")"
);
这样,整个图表在<g>
。
<强> 2。 panRight()强>
您正在移动圆圈和线条两次:首先使用新比例,第二个使用.attr("transform", d3.event.transform)
。所以只需删除以下三行
usageAreaPath.attr("transform", d3.event.transform);
usageLinePath.attr("transform", d3.event.transform);
circles.attr("transform", d3.event.transform);
修改强>
我刚才意识到,缩放功能根本不起作用。在平移期间(也在我的解决方案中)一直调用重绘函数。因此,平移执行两次。如果缩放函数中的“if语句”可行,则panRight()函数将是必需的。所以关注这个if / else语句。一种选择可以是区分鼠标滚轮和拖动事件,例如,
if(d3.event.sourceEvent.toString() === "[object MouseEvent]")
。因此在平移过程中不会调用重绘函数,但仍存在一些缩放问题。也许this可以提供帮助。
答案 1 :(得分:-1)
我不知道你的目标是什么,我在上面的答案解决你的问题,也许你只是没有停止事件使用d3.event.defaultPrevented()
如果你想要停止事件
function panRight(){
d3.event.defaultPrevented()//use it so it will reset the event
console.log('panRight',d3.event.transform);
var new_xScale = d3.event.transform.rescaleX(x2)
gX.call(xAxis.scale(new_xScale));
usageAreaPath.attr("transform", d3.event.transform);
usageLinePath.attr("transform", d3.event.transform);
circles.attr("transform", d3.event.transform);
}
//the result is normal ordinary chart
但如果您在重绘()上使用d3.event.defaultPrevented()
取消标记,则结果是一个奇怪的图表
function redraw(){
//d3.event.defaultPrevented()
var domain,
minBuffer,
maxBuffer,
panDelta1,
panDelta2,
t;
t = d3.event.transform;
console.log('redraw',d3.event.transform);
// console.log(t.rescaleX(x2).domain());
// console.log(xScale.domain());
//d3.event.defaultPrevented()
xScale.domain(t.rescaleX(x2).domain());
xAxis = d3.axisBottom(xScale).tickSize(0).tickFormat(d3.timeFormat('%b'));
focus.select(".axis--x").call(xAxis);
usageAreaPath.attr("d", area);
usageLinePath.attr('d',line);
//d3.event.defaultPrevented()
focus.selectAll('.circle')
.attr('cx', function(d) { return xScale(getDate(d)); })
.attr('cy', function(d) { return yScale(d.kWh); })
.attr("transform", "translate(0," + 80 + ")");
}