我现在正在构建一个从 postgres 后端获取数据的图表。对于 x 轴的构建,我有以下内容:
var x = d3.scaleTime()
.domain(d3.extent(data_prices, function(d){
var time = timeParser(d.timestamp);
return time;
}))
.range([0,width])
其中 timeParser 是表示 d3.timeParse() 的函数。
我有一个数据点在 16:58,另一个在 22:06,它看起来有点难看,因为它只是像那样粘在一边。我怎么说,例如,是否有轻微的填充,比如每个 +/- 30 分钟,并在每一端继续趋势线路径? (或者至少只是第一部分)
最佳答案
要在时间范围内创建填充,请使用 interval.offset
。根据API :
Returns a new date equal to date plus step intervals. If step is not specified it defaults to 1. If step is negative, then the returned date will be before the specified date.
让我们看看它的工作原理。这是一个基于时间尺度的轴,其最小值和最大值与您的相似:
var svg = d3.select("svg");
var data = ["16:58", "18:00", "20:00", "22:00", "22:06"].map(function(d) {
return d3.timeParse("%H:%M")(d)
});
var scale = d3.scaleTime()
.domain(d3.extent(data))
.range([20, 580]);
var axis = d3.axisBottom(scale);
var gX = svg.append("g")
.attr("transform", "translate(0,50)")
.call(axis)
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="600" height="100"></svg>
现在,要创建填充,我们只需要在极端情况下减去和增加 30 分钟:
var scale = d3.scaleTime()
.domain([d3.timeMinute.offset(d3.min(data), -30),
//subtract 30 minutes here --------------^
d3.timeMinute.offset(d3.max(data), 30)
//add 30 minutes here ------------------^
])
.range([20, 580]);
结果如下:
var svg = d3.select("svg");
var data = ["16:58", "18:00", "20:00", "22:00", "22:06"].map(function(d) {
return d3.timeParse("%H:%M")(d)
});
var scale = d3.scaleTime()
.domain([d3.timeMinute.offset(d3.min(data), -30), d3.timeMinute.offset(d3.max(data), 30)])
.range([20, 580]);
var axis = d3.axisBottom(scale);
var gX = svg.append("g")
.attr("transform", "translate(0,50)")
.call(axis)
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="600" height="100"></svg>
请记住,此解决方案不会将极端滴答舍入到最接近的半小时:它加和减去半小时.
因此,要四舍五入到最接近的半小时,您可以使用 Math.floor
和 Math.ceil
进行简单的数学运算:
.domain([
d3.min(data).setMinutes(Math.floor(d3.min(data).getMinutes() / 30) * 30),
d3.max(data).setMinutes(Math.ceil(d3.max(data).getMinutes() / 30) * 30)
])
这是演示:
var svg = d3.select("svg");
var data = ["16:58", "18:00", "20:00", "22:00", "22:06"].map(function(d) {
return d3.timeParse("%H:%M")(d)
});
var scale = d3.scaleTime()
.domain([d3.min(data).setMinutes(Math.floor(d3.min(data).getMinutes() / 30) * 30), d3.max(data).setMinutes(Math.ceil(d3.max(data).getMinutes() / 30) * 30)])
.range([20, 580]);
var axis = d3.axisBottom(scale);
var gX = svg.append("g")
.attr("transform", "translate(0,50)")
.call(axis)
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="600" height="100"></svg>
关于javascript - 将时间刻度的 x 轴舍入到最接近的半小时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48024914/