在 D3 轴上形成分和秒

Nic*_*len 4 javascript time axis d3.js

我正在处理一个 D3 项目,其中我有 JSON 格式的时间(分钟和秒),如下所示:

"Time": "36:50"
Run Code Online (Sandbox Code Playgroud)

如何在 D3 图形的 y 轴上以该格式绘制时间?我应该使用d3.scaleTime还是d3.scaleLinear用于轴?如何制作minute:second以 JSON 格式显示时间的刻度?

编辑:
这是我迄今为止的尺度/轴:

  //Format data for X Axis
      var yearFormat = "%Y";
      var parsedYear = years.map(function(d) {
        return d3.timeParse(yearFormat)(d)
      });


      var x = d3.scaleTime()
                .range([0, width])
                .domain(d3.extent(parsedYear));


      // Format data for Y Axis
      var specifier = "%M:%S";
      var parsedTime = times.map(function(d) {
        return d3.timeParse(specifier)(d)
      })

      var y = d3.scaleTime()
                .range([height, 0])
                .domain(d3.extent(parsedTime));

      // X Axis
      g.append("g")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x))
        .attr("stroke-width", 2)
        .style("font-size", ".6em")


      // Y Axis
      g.append("g")
        .call(d3.axisLeft(y))
        .attr("stroke-width", 2)
        .style("font-size", ".6em")
        .tickValues(parsedTime)
        .tickFormat(function(d){
           return d3.timeFormat(specifier)(d)
         });
Run Code Online (Sandbox Code Playgroud)

Ger*_*ado 5

您的问题的任何可能答案都危险地基于意见,因为这完全取决于您想要什么:您想将时间视为时间吗?或者您想将时间视为单独的、个别的事件?

这里实际上有三个选项供您选择:

  1. 使用序数尺度(带、点...):在这种情况下,每个数据条目将只是一个分类变量。轴上刻度之间的空间将相同。
  2. 使用线性刻度:这允许轴上刻度的不同距离。但是,这些值不会是时间,您必须创建一个数学来设置这些值(最简单的方法可能是计算秒数)。
  3. 使用时间尺度:这有一个优势,即您将时间视为时间。然而,主要的缺点正是之前的陈述:时间是一个复杂的野兽,你会有闰年、夏令时、时区差异等......

由于线性刻度的创建非常简单(而序数刻度更简单),这里有一个答案,显示了如何使用时间刻度来实现。

假设你有这个数据数组:

var data = ["12:32", "21:05", "24:56", "36:30", "45:14", "71:11"];
Run Code Online (Sandbox Code Playgroud)

第一步是解析日期:

var specifier = "%M:%S";
var parsedData = data.map(function(d) {
  return d3.timeParse(specifier)(d)
});
Run Code Online (Sandbox Code Playgroud)

然后创建规模:

var scale = d3.scaleTime()
  .domain(d3.extent(parsedData));
Run Code Online (Sandbox Code Playgroud)

为此,我们必须tickValues使用我们解析的数据数组设置 ,并格式化分钟和秒的刻度:

var axis = d3.axisBottom(scale)
    .tickValues(parsedData)
    .tickFormat(function(d){
        return d3.timeFormat(specifier)(d)
    });
Run Code Online (Sandbox Code Playgroud)

结果如下:

var data = ["12:32", "21:05", "24:56", "36:30", "45:14", "71:11"];
Run Code Online (Sandbox Code Playgroud)
var specifier = "%M:%S";
var parsedData = data.map(function(d) {
  return d3.timeParse(specifier)(d)
});
Run Code Online (Sandbox Code Playgroud)

如您所见,这里的刻度是正确间隔的。但是我们有一个问题:那些刻度是实际日期(如果您检查代码,您会看到年份是 1900)。因此,应为 71 分 11 秒的最后一个刻度显示为11:11,因为它是下一小时的第 11 分钟。

一个简单的解决方案是引用原始字符串数组:

.tickFormat(function(d,i) {
    return data[i]
});
Run Code Online (Sandbox Code Playgroud)

结果如下:

var scale = d3.scaleTime()
  .domain(d3.extent(parsedData));
Run Code Online (Sandbox Code Playgroud)
var axis = d3.axisBottom(scale)
    .tickValues(parsedData)
    .tickFormat(function(d){
        return d3.timeFormat(specifier)(d)
    });
Run Code Online (Sandbox Code Playgroud)