当迈克说你将把大部分时间花在处理数据上时,我想他不是在开玩笑。好吧,我最终编写了一个相当长的算法来插入数据集中缺失的日期。它的工作原理是将所有当前日期提取到一个数组中,将它们转换为毫秒时间,成对迭代日期并填充天数等于对之间差异的天数(getMissingDates() 函数中的 while 循环),然后构建一个JSON 字符串与它们,最后将这个新的 JSON 字符串与原始输入数据合并,然后按升序排序。
这是我想出的:
d3.json("/users/" + user_id + "/workouts/analyze.json", function(error, response) {
data = response;
deriveMissingDates();
//
function deriveMissingDates() {
date_array = getCurrentDates();
missingDates = getMissingDates(date_array);
new_json = buildJSONFromMissingDates(missingDates);
new_data = mergeMissingDates(new_json);
sortJSON(data);
}
// Get all current dates in dataset
// @param date_array.
function getCurrentDates(date_array) {
var date_array = [];
for (i = 0; i < data.length; i++) {
var json_object = " {\"date\":\"" + data[i].date + "\", \"load_volume\":\"" + data[i].load_volume + "\"},"
date_array.push(json_object.slice(10,20));
}
return date_array;
}
// Interpolates missing dates.
// @param arr. Array of current dates in original data set.
function getMissingDates(arr) {
var predptr = 0, leadptr = 1, missingDates = []; // initialize predecessor pointer, lead pointer, and missing dates array
while (true) {
if (predptr == arr.length) break;
var firstDate = new Date(arr[predptr]).getTime();
var secondDate = new Date(arr[leadptr]).getTime();
var currentDate = firstDate + ((24 * 60 * 60 * 1000) * 2);
var d = new Date(currentDate);
while (currentDate <= secondDate) { // Push missing dates onto array.
var d = new Date(currentDate);
missingDates.push(d.getFullYear() + '-' + ('0' + (d.getMonth()+1)).slice(-2) + '-' + ('0' + d.getDate()).slice(-2));
currentDate += (24 * 60 * 60 * 1000); // add one day
}
predptr++;
leadptr++;
}
return missingDates;
}
// Builds JSON string from missingDates array.
// @param arr. Array with each missing date.
function buildJSONFromMissingDates(arr) {
json = ""
for (i = 0; i < arr.length; i++) {
json += "{\"date\":" + "\"" + arr[i] + "\",\"stub\":" + true + ",\"load_volume\":" + 200 + "},";
}
json = json.slice(0,json.length-1);
json = "[" + json + "]";
json = $.parseJSON(json);
return json;
}
// Concatenate missingDates array with original input data
// @param new_json. New JSON string built from missing date values.
function mergeMissingDates(new_json) {
data = data.concat(new_json);
var content = [];
for (i=0; i < data.length; i++) {
content += "{" + data[i].date + "," + data[i].load_volume + "},";
}
return data;
}
// Sort new JSON dataset in ascending order.
// @param data. New JSON data with missing date objects.
function sortJSON(data) {
for (i = 0; i < data.length; i++) {
data[i].date = new Date(data[i].date).getTime(); // convert dates to millisecond time
}
data.sort(function(a,b) { return parseInt(a.date) - parseInt(b.date) });
}
然后我连接到存根布尔值以应用不同的样式,如下所示:
.style("fill", function(d) {
if (d.stub == true) {
return "#dddddd"
} else {
return "#00e0fe"
}});
JSON 输出(日期以毫秒为单位,存根高度为 200):
[{"date":1366416000000,"load_volume":400},{"date":1366502400000,"stub":true,"load_volume":200},{"date":1366588800000,"stub":true,"load_volume":200},{"date":1366675200000,"load_volume":400},{"date":1366761600000,"load_volume":400},{"date":1366848000000,"stub":true,"load_volume":200},{"date":1366934400000,"stub":true,"load_volume":200},{"date":1367020800000,"stub":true,"load_volume":200},{"date":1367107200000,"load_volume":1732},{"date":1367193600000,"stub":true,"load_volume":200},{"date":1367280000000,"load_volume":400}]
结果如下:
我可能会尝试重构代码以查看是否可以使其更简洁,但我只是想让它首先工作。