从零开始d3轴时间刻度

时间:2018-09-11 05:23:26

标签: javascript d3.js data-visualization

我正在创建使用时间刻度的图形。我希望X轴显示从零开始的时间,并以每5秒为间隔进行计数。

--------------------------------
:00  :05  :10  :15  :20  :25  :30

我的数据具有时间戳,这些时间戳被强制为日期对象。比例基于这些时间戳。

(注意:我正在使用d3 v4 / 5)。

D3具有显示时间间隔的漂亮功能,但是间隔从数据对象中的时间开始。

我可以转换数据,使所有时间都从零开始,但是当我在同一时间范围内排列多个数据集时,它将产生其他问题。我想知道是否有一种更优雅的方法来使用刻度线格式设置功能之一来显示与刻度不同的刻度线,或者从零秒开始即时计算。

谢谢。

编辑:这是一个更完整的代码段。

var videoData = [{
    "id": "1",
    "user_id": "_jlxvt8445494296",
    "video_id": "test",
    "time": "2018-09-11 15:39:20",
    "metric": "4"
  },
  {
    "id": "2",
    "user_id": "_jlxvt8445494296",
    "video_id": "test",
    "time": "2018-09-11 15:39:26",
    "metric": "2"
  },
  {
    "id": "3",
    "user_id": "_jlxvt8445494296",
    "video_id": "test",
    "time": "2018-09-11 15:39:27",
    "metric": "3"
  },
  {
    "id": "4",
    "user_id": "_jlxvt8445494296",
    "video_id": "test",
    "time": "2018-09-11 15:39:38",
    "metric": "1"
  }
];

var svg = d3.select("svg"),
  width = 400,
  height = 200;

var parseTime = d3.timeParse("%Y-%m-%d %H:%M:%S");

//coerce to d3 timeParse object
videoData.forEach(function(d) {
  d.time = parseTime(d.time);
});

var x = d3.scaleTime()
  .rangeRound([0, width])
  .domain(d3.extent(videoData, function(d) {
    return d.time;
  }));

var y = d3.scaleLinear()
  .rangeRound([height, 0])
  .domain(d3.extent(videoData, function(d) {
    return d.metric;
  }));


var line = d3.line()
  .x(function(d) {
    return x(d.time);
  })
  .y(function(d) {
    return y(d.metric);
  })
  .curve(d3.curveBasis);


svg.append("g")
 .attr("transform", "translate(10," + height + ")")
 .call(d3.axisBottom(x).tickFormat(d3.timeFormat(":%S")));

svg.append("path")
  .datum(videoData)
  .attr("fill", "none")
  .attr("stroke", "steelblue")
  .attr("d", line);
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg width="420" height="220"></svg>

1 个答案:

答案 0 :(得分:0)

您必须相对于视频的开头进行所有计算。

计算ms与视频开始之间的时差,并将该ms-time转换为日期new Date(ms)。您可以使用datevar.getTime()获取日期的毫秒时间。

要越过时区,您必须以UTC显示所有时间。

在显示时间从00:00到01:40的轴的下面,这是前100秒,每5秒钟是一个刻度。

var parseTime = d3.timeParse("%Y-%m-%d %H:%M:%S");//2018-09-10 21:06:34

var formatSecond = d3.utcFormat(":%S"),
    formatMinute = d3.utcFormat("%M:%S");

function multiFormat(date) {
  return (d3.timeMinute(date) < date ? formatSecond : formatMinute)(date);
}

var width = 500;
var height = 100;
var g = d3.select("#chart").append("svg").attr("width", width + 40).attr("height", height + 40)
          .append("g").attr("transform", "translate(20,20)");

var x = d3.scaleUtc()
    .rangeRound([0, width])
    //.domain(d3.extent(data, function(d) { return d.time; }));
    .domain([new Date(0), new Date(100*1000)]);

g.append("g")
  .attr("transform", "translate(0," + height + ")")
  //.call(d3.axisBottom(x).ticks(d3.timeSecond.every(5)));
  .call(d3.axisBottom(x).ticks(d3.utcSecond.every(5)).tickFormat(multiFormat));
<script src='http://d3js.org/d3.v5.min.js' charset='utf-8'></script>
<div id="chart"></div>