我正在创建一个使用时间刻度的图表。我希望X轴显示从零开始的时间,并以每个5秒的间隔计数。
--------------------------------
:00 :05 :10 :15 :20 :25 :30
我的数据有时间戳,它们被强制转换为日期对象。比例基于这些时间戳。
(注意:我正在使用d3 v4 / 5)。
D3具有显示时间间隔的漂亮功能,但间隔从数据对象中的时间开始。
我可以转换我的数据,所以所有时间都从0开始,但是当我在同一时间范围内排列多个数据集时,它会产生其他问题。我想知道是否有一种更优雅的方式来使用其中一个刻度格式化函数来显示与刻度不同的刻度或者从零开始计算。
提前致谢。
编辑:这是一个更完整的代码片段。
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>
您必须相对于视频的开头进行所有计算。
计算ms
相对于视频开头的时差,并将该ms时间转换为日期new Date(ms)
。你得到datevar.getTime()
日期的ms时间。
要超过时区,您必须以UTC格式显示所有时间。
在显示从00:00到01:40的时间的轴下方,前5秒,每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>