当给定在 C3js 图表中呈现的一组非连续日期时,会直接在点之间绘制线条。是否有一个设置允许 C3js 将未提供的天数解释为值为 0,这样非连续天之间的行将在中间的天数中首先降至值 0,然后再回升到下一个提供的天数?
我可以想象,一个临时的替代方案是使用条形图,但我更喜欢折线图。
上图是不良结果的图像,其中分散的数据点直接连接,而在干预期间没有下降到值 0。
临时解决方案
作为临时解决方案,我创建的一个方法是编写一个函数,该函数仅生成一个日期数组,该日期数组从日期值数组的第一个日期到最后一个日期。它为原始日期数组中索引为 -1 的日期提供 0 值。
var newKeysDay = getDatesArray(firstDay, lastDay);
var newValsDay = [];
newKeysDay.forEach(function (day) {
var i = keysDay.indexOf(day);
if (i > -1) newValsDay.push(valsDay[i]);
else newValsDay.push(0);
});
最佳答案
问题是 c3 不会将缺失的日期解释为空或 0,而只是将您未声明感兴趣的日期解释为,因此您的解决方案看起来是正确的选择。
我假设您已经将 connectNull
设置为 true,因为您的屏幕截图有两个系列,其中一些数据点存在于一个系列中而不是另一个系列中,但它们像 connectNull 一样被跳过
就可以了。
您可以通过仅在现有日期之前和之后放置“零天”而不填写所有中间日期来提高代码效率。示例改编自http://c3js.org/samples/timeseries.html 。它可能会渲染得更快一些,并且不会产生大量额外的滴答声。
var dates = ['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-11', '2013-01-08', '2013-01-09', '2013-05-02'],
val1 = [30, 200, null, 400, 150, 250],
val2 = [130, 340, 200, 500, 250, 350];
var dateSet = d3.set(dates);
var df = d3.time.format("%Y-%m-%d");
var addIfNeeded = function (d, inc) {
var nbour = new Date (d);
nbour.setDate (nbour.getDate() + inc);
var nf = df(nbour);
if (!dateSet.has(nf)) {
dateSet.add (nf);
dates.push (nf);
val1.push (0);
val2.push(0);
};
}
dates.slice(0).forEach (function(date) {
var d = new Date(date);
if (val1[i] === null) { val1[i] = 0; }
if (val2[i] === null) { val2[i] = 0; }
addIfNeeded (d, 1);
addIfNeeded (d, -1);
})
console.log ("dates", dates, val1, val2);
var chart = c3.generate({
data: {
x: 'x',
columns: [
['x'].concat(dates),
['data1'].concat(val1),
['data2'].concat(val2)
]
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%Y-%m-%d'
}
}
}
});
关于d3.js - 假设没有数据的日期值为 0(C3js 时间序列图),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39298354/