javascript - 将时间刻度的 x 轴舍入到最接近的半小时

标签 javascript d3.js

My current graph

我现在正在构建一个从 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.floorMath.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/

相关文章:

javascript - D3.js 可折叠树 - 展开/折叠节点

javascript - 如何将参数传递给ajax函数的回调

javascript - 变换旋转和翻转效果——CSS3和jQuery

javascript - DataTables 表不显示

php - 如何在 jquery-ajax 中发布值数组?

javascript - 我如何将 href 应用于整个 svg?

javascript - d3.json() 回调中的代码未执行

css - 录制 SVG 动画并将其保存为动画 GIF

javascript - lof JSliderNews 不起作用

d3.js - 不同比例的多个 Y 轴和路径