我正在一个问题域工作,我需要以毫秒的时间间隔显示数据。我发现当你在图表上放大得足够远时,缩放/平移功能的行为会突然改变!如果您使用的是时间刻度,则会在轴开始显示毫秒时发生这种情况。
具体来说,行为改变是d3如何缩放鼠标光标。对于以秒或更高为单位测量的间隔,网格线相对于光标位置进行缩放。鼠标停留在下午6点,滚动将导致下午6点占用更多空间。但是一旦达到毫秒,无论光标位置如何,网格似乎都会从最左边缩放。平移也会停止轴的移动。
我在d3中不是很有经验,但对我来说,这看起来像个bug。我在缩放文档中没有看到任何关于此的内容。是否有这样的原因,如果是这样的话,它可以以某种方式被覆盖吗?
在下面的链接中,只要缩放得足够远以使x轴标签从:YY变为.YYY(即:50到.653),您应该会看到问题。
这显示了“损坏”的行为:http://jsfiddle.net/JonathanPullano/LuYDY/3/
这显示了“正确”行为:http://jsfiddle.net/JonathanPullano/LuYDY/2/
编辑:我发现问题不在于缩放行为,而在于time.scale()本身。我做了另一个小提琴,使用setTimeout自动重新缩放轴而不使用缩放。问题仍然存在。试试吧。http://jsfiddle.net/JonathanPullano/LuYDY/4/
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var x = d3.time.scale()
.domain([-5000, 5000])
.range([0, width]);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("rect")
.attr("width", width)
.attr("height", height);
var gXAxis = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
function chart(selection) {
selection.each(function(data) {
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5)
.tickSize(-height);
gXAxis.call(xAxis);
});
}
update();
function update() {
var start = new Date(x.domain()[0].getTime() + 10);
var end = new Date(x.domain()[1].getTime() - 10);
if(start.getTime() < end.getTime()) {
x.domain([start,end]);
setTimeout(update,10);
}
svg.call(chart);
}
答案 0 :(得分:1)
缩放和平移的行为符合预期,但每次都会以不同的值绘制刻度线/网格线,这使得它在开始时看起来不稳定,并且在极端缩放时使其看起来像网格不移动。
我修改了你的小提琴以使用更完整的刻度格式功能,并且每次在同一点(刻度上)绘制一个圆圈:
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5)
.tickSize(-height)
.tickFormat(d3.time.format("%H:%M.%L") );
正如您所看到的,值按预期变焦和平移,但是刻度值总是在窗口上的相同点处间隔,而不是在圆形的毫秒数处。
该错误只是时间尺度的“漂亮”圆形日期时间值的定义在此范围内分崩离析。明确地将比例称为.nice()
也不起作用。
时间刻度方法试图找到一个合适的时间单位来选择刻度,当整个域小于1秒时,这种方法不起作用。如果它切换到“好”的线性标度定义(即,舍入到10的倍数),那将是理想的。
即。如果你这样做:
x = d3.time.scale()
.domain([10, 477])
.nice();
然后查询x域并将值转换回整数,你仍然得到[10,477]。如果您使用线性刻度执行此操作,则域将舍入为[0,500]。同样,该时间刻度的刻度值放在域的精确分数处,但是放在线性刻度的圆数处。
你可以在github上发出这个问题请求。与此同时,如果您的数据域在毫秒范围内,可能只需使用线性刻度。