使用刻度时,为什么初始拖动位置不正确?

时间:2014-02-14 13:09:40

标签: javascript d3.js

我正在尝试实现一个滑块。它应该允许沿水平轴拖动元素并获得相应的整数值。在我介绍比例之前,我没有遇到任何问题。

这是小提琴。一旦我们开始拖动,就会看到不正确的行为。之后它似乎正确地工作。

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/

如何防止最初的错误行为?

3 个答案:

答案 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

开始位置没问题,但可能有更好的方法来解决这个问题。

Fiddle

编辑:

像这样设置。 (还包括如上所述删除scale.invert(d.x)):

var number = 50;

var slider = svg.selectAll('circle')
    .data([{ x: scale(number), y: h / 2 }]);

Updated fiddle.

答案 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);

请参阅updated JsFiddle