我正在尝试实现一个滑块。它应该允许沿水平轴拖动元素并获得相应的整数值。在我介绍比例之前,我没有遇到任何问题。
这是小提琴。一旦我们开始拖动,就会看到不正确的行为。之后它似乎正确地工作。
slider.enter().append('circle')
.attr('r', r)
.attr('cx', function(d) { return scale(d.x); })
.attr('cy', function(d) { return d.y })
.call(drag)
function dragmove(d) {
var x = Math.max(r, Math.min(w - r, d3.event.x)),
numberNow = scale.invert(x)
slider.attr("cx", d.x = x)
d3.select('#value').text(numberNow)
}
http://jsfiddle.net/hanbzu/NkStD/
如何防止最初的错误行为?
答案 0 :(得分:1)
对d3.js
没有任何线索,但我注意到通过更改此内容:
slider.enter().append('circle')
.attr('r', r)
.attr('cx', function(d) { return d.x; /* scale.invert(d.x) */ })
.attr('cy', function(d) { return d.y; }) // problem? --^
.call(drag);
它从一开始就拖得很好。但最初的价值是错误的。
通过将号码设置为:
var number = 400 / 100 * 50;
// I scaled down width to 400
开始位置没问题,但可能有更好的方法来解决这个问题。
像这样设置。 (还包括如上所述删除scale.invert(d.x)
):
var number = 50;
var slider = svg.selectAll('circle')
.data([{ x: scale(number), y: h / 2 }]);
答案 1 :(得分:0)
问题是你没有缩放你正在设置的值:
slider.attr("cx", d.x = x)
您传递的是d.x
而不是scale(d.x)
,而您最初用于设置值。通过缩放两个值来解决:
slider.attr("cx", scale(d.x = x))
完整示例here。
答案 2 :(得分:0)
我找到了一种方法来修复初始行为而不更改我通过d3提供的'数据'。我使用origin
方法如下:
var drag = d3.behavior.drag()
.origin(function() {
var t = d3.select(this)
return { x: t.attr("cx"), y: t.attr("cy") }
})
.on('drag', dragmove);