我正在尝试使用D3绘制时间序列数据并遇到缺少时间戳和宽度调整的问题。数据通常在每5分钟后出现,但由于某种原因,有时您可能没有时间戳。 (例如,上午11:45之后的下一次邮票将是23:45)。我希望在中间有一个间隙,而不是在那个时间段连接它们的线。我想我必须在每5分钟后在一个新数组中放置一个空值并用它来绘制图形。请让我知道如何去做,因为我是d3和java脚本的新手
Working jsfiddle to illustrate the issue
代码:
var data = [
{"mytime": "2015-12-01T11:10:00.000Z", "value": 64},
{"mytime": "2015-12-01T11:15:00.000Z", "value": 67},
{"mytime": "2015-12-01T11:20:00.000Z", "value": 70},
{"mytime": "2015-12-01T11:25:00.000Z", "value": 64},
{"mytime": "2015-12-01T11:30:00.000Z", "value": 72},
{"mytime": "2015-12-01T11:35:00.000Z", "value": 75},
{"mytime": "2015-12-01T11:40:00.000Z", "value": 71},
{"mytime": "2015-12-01T11:45:00.000Z", "value": 80},
{"mytime": "2015-12-01T11:45:00.000Z", "value": 80},
{"mytime": "2015-12-02T11:45:00.000Z", "value": 80},
{"mytime": "2015-12-02T11:45:00.000Z", "value": 80}
];
var parseDate = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ").parse;
data.forEach(function(d) {
d.mytime = parseDate(d.mytime);
});
//var margin = { top: 30, right: 30, bottom: 40, left:50 },
var margin = { top: 30, right: 30, bottom: 40, left:50 },
height = 200,
width = 800;
var color = "green";
var xaxis_param = "mytime";
var yaxis_param = "value"
var params1 = {margin:margin,height:height,width:width, color: color, xaxis_param:xaxis_param, yaxis_param :yaxis_param};
draw_graph(data,params1);
function draw_graph(data,params){
//Get the margin
var xaxis_param = params.xaxis_param;
var yaxis_param = params.yaxis_param;
var color_code = params.color;
var margin = params.margin;
var height = params.height - margin.top - margin.bottom,
width = params.width - margin.left - margin.right;
console.log("1")
var x_extent = d3.extent(data, function(d){
return d[xaxis_param]});
console.log("2")
var y_extent = d3.extent(data, function(d){
return d[yaxis_param]});
var x_scale = d3.time.scale()
.domain(x_extent)
.range([0,width]);
console.log("3")
var y_scale = d3.scale.linear()
.domain([0,y_extent[1]])
.range([height,0]);
//Line
var lineGen = d3.svg.line()
.x(function (d) {
return x_scale(d[xaxis_param]);
})
.y(function (d) {
return y_scale(d[yaxis_param]);
});
var myChart = d3.select('body').append('svg')
.style('background', '#E7E0CB')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate('+ margin.left +', '+ margin.top +')');
myChart
.append('svg:path')
.datum(data)
.attr('class', 'line')
.attr("d",lineGen)
.attr('stroke', color_code)
.attr('stroke-width', 1)
.attr('fill', 'none');
var legend = myChart.append("g")
.attr("class", "legend")
.attr("transform", "translate(" + 5 + "," + (height - 25) + ")")
legend.append("rect")
.style("fill", color_code)
.attr("width", 20)
.attr("height", 20);
legend.append("text")
.text(yaxis_param)
.attr("x", 25)
.attr("y", 12);
var vGuideScale = d3.scale.linear()
.domain([0,y_extent[1]])
.range([height, 0])
var vAxis = d3.svg.axis()
.scale(vGuideScale)
.orient('left')
.ticks(5)
var hAxis = d3.svg.axis()
.scale(x_scale)
.orient('bottom')
.ticks(d3.time.minute, 5);
myChart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(hAxis);
myChart.append("g")
.attr("class", "y axis")
.call(vAxis)
}
编辑: 下面是数据集的图像(正如你可以看到,当我有空值时,图表是不连续的,但在实际数据中,我将没有那些空值的时间戳,它将从23:45到00:00)
var data = [{"mytime": "2015-12-01T23:10:00.000Z", "value": 64},
{"mytime": "2015-12-01T23:15:00.000Z", "value": 67},
{"mytime": "2015-12-01T23:20:00.000Z", "value": 70},
{"mytime": "2015-12-01T23:25:00.000Z", "value": 64},
{"mytime": "2015-12-01T23:30:00.000Z", "value": 72},
{"mytime": "2015-12-01T23:35:00.000Z", "value": 75},
{"mytime": "2015-12-01T23:40:00.000Z", "value": 71},
{"mytime": "2015-12-01T23:45:00.000Z", "value": 80},
{"mytime": "2015-12-01T23:50:00.000Z", "value": null},
{"mytime": "2015-12-01T23:55:00.000Z", "value": null},
{"mytime": "2015-12-02T00:00:00.000Z", "value": 80},
{"mytime": "2015-12-02T00:05:00.000Z", "value": 85}
];
答案 0 :(得分:0)
为了达到你想要的效果,你必须将数据分开。
d3
' line
函数将数据列表解释为单行的坐标,无论两点之间的距离如何。因此,如果您想在两条线(实际上代表两条不同的线)之间显示间隙,则需要单独绘制它们。
使用工作示例查看fiddle的分支。
答案 1 :(得分:0)
我已经根据一些固定的时间跨度将数据分组在一起做了类似的事情,我认为在你的情况下它将是15分钟。像这样:
function group_data_missing (arr) {
// Group the data into buckets so that missing data is handled properly
var timespan;
//this gives 15 minutes in milliseconds
timespan = 15 * 60 * 1000;
var dg = [];
var group = [arr[0]];
for (var i=1; i<arr.length; i++) {
if (arr[i].date.getTime() - arr[i-1].date.getTime() > timespan) {
dg.push(group);
group = [];
} else {
group.push(arr[i]);
}
}
dg.push(group);
return dg;
}
这将创建一个数组数组,每个数组都是一个连续长达15分钟的线段。然后分别绘制每一个。
或者,如果您有一些连续的日期范围,其中一些实际值为null,则可以使用行定义上的.defined
method。