我正在使用一个包含某些tweet数据的.csv,created_at字段为datetime,例如:2018-07-17 12:08:45(列名为:TweetTime)。
使用D3.js,我希望能够在日期时间x轴上绘制我的推文。到目前为止,这证明是不可能的吗?请给我任何建议!
以下相关代码段:
d3.csv('daniellatweets180718.csv', function(data){
circles = svg.selectAll('.dot')
.data(data)
.enter()
.append('circle')
.attr('class','dot')
.attr('cx',function(d){
var cleandate = d3.timeParse("%Y-%m-%d %H:%M:%S")(d.TweetTime)
console.log('test' + cleandate);
return cleandate;
})
虽然显示test +的日期是控制台的完整日期,但实际上并没有在我的vis上显示圆圈。
我尝试了很多事情,但我不明白怎么了?
答案 0 :(得分:0)
您试图通过使用日期作为像素值来将元素定位在像素中。这行不通。即使将日期强制为原始值,您也将获得自纪元开始以来的毫秒数,这将不等于您想要的像素位置:
var date = new Date();
console.log(date.valueOf());
您想使用磅秤。 d3.scaleTime允许您将日期/时间从给定域转换为给定范围的输出值,在这种情况下为像素值。可能看起来像:
var scale = d3.scaleTime()
.domain(d3.extent(data, function(d) { return d3.timeParse("%Y-%m-%d")(d.tweettime); }))
.range([margin.left,width+margin.left])
d3.extent将基于提供的数据和属性提供域的范围,而range将提供缩放值的范围。这样,我们可以将域中的任何值缩放到范围内的值。要将日期缩放为像素值,我们将使用scale(value)
:
记录每个cx
属性的缩放值以进行演示
var data = [
{tweettime:"2018-04-04"},
{tweettime:"2017-03-03"},
{tweettime:"2016-02-02"},
{tweettime:"2015-01-01"}
];
var width = 300;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", 200);
var scale = d3.scaleTime()
.domain(d3.extent(data, function(d) { return d3.timeParse("%Y-%m-%d")(d.tweettime); }))
.range([0,width])
var circles = svg.selectAll('.dot')
.data(data)
.enter()
.append('circle')
.attr('class','dot')
.attr("cy", 100)
.attr("r", 10)
.attr('cx',function(d){
var cleandate = d3.timeParse("%Y-%m-%d")(d.tweettime)
return scale(cleandate);
})
circles.each(function(d) {
console.log(d3.select(this).attr("cx"));
})
<script src="https://d3js.org/d3.v5.min.js"></script>
如果首先将日期字符串转换为日期,我们当然可以节省一些时间(这样一来,我们就无需解析刻度的日期字符串,也不需要向刻度输入数据了,我还添加了左右的边距,在此过程中修改比例范围):
var data = [
{tweettime:"2018-04-04"},
{tweettime:"2017-03-03"},
{tweettime:"2016-02-02"},
{tweettime:"2015-01-01"}
];
data.forEach(function(d) {
d.tweettime = d3.timeParse("%Y-%m-%d")(d.tweettime);
})
var margin = {left: 20, right:20}
var width = 300 - margin.left - margin.right;
var svg = d3.select("body").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", 200);
var scale = d3.scaleTime()
.domain(d3.extent(data, function(d) { return d.tweettime; }))
.range([margin.left,width+margin.left])
var circles = svg.selectAll('.dot')
.data(data)
.enter()
.append('circle')
.attr('class','dot')
.attr("cy", 100)
.attr("r", 10)
.attr('cx',function(d){
return scale(d.tweettime);
})
circles.each(function(d) {
console.log(d3.select(this).attr("cx"));
})
<script src="https://d3js.org/d3.v5.min.js"></script>