As we discussed in the comments, the important problem is that dc.js will only draw the data it receives. It doesn't know if data is missing, so we will need to fill in the null
s in order to draw gaps in the line.
I linked to a previous question, where the data is timestamps. The answer there uses a d3 time interval to generate the missing timestamps.
However, your data uses integers for keys (even though it represents weeks), so we will need to change the function a little bit:
function fill_ints(group, fillval, stride = 1) { // 1
return {
all: function() {
var orig = group.all();
var target = d3.range(orig[0].key, orig[orig.length-1].key, stride); // 2
var result = [];
for(var oi = 0, ti = 0; oi < orig.length && ti < target.length;) {
if(orig[oi].key <= target[ti]) {
result.push(orig[oi]);
if(orig[oi++].key === target[ti])
++ti;
} else {
result.push({key: target[ti], value: fillval});
++ti;
}
} // 3
if(oi<orig.length) // 4
Array.prototype.push.apply(result, orig.slice(oi));
if(ti<target.length) // 5
result = [...result, ...target.slice(ti).map(t => ({key: t, value: fillval}))];
return result;
}
};
}
Now we wrap our original group using this function, creating a "fake group":
const filledGroup = fill_ints(capacityGroup, {average: null});
and pass it to the chart instead:
.group(filledGroup);
One weakness of using LineChart.defined(), and the underlying d3.line.defined, is that it takes two points to make a line. If you have isolated points, as week 1 is isolated in your original data, then it won't be shown at all.
In this demo fiddle, I have avoided the problem by adding data for week 2.
But what about isolated dots?I was curious how to solve the "isolated dots problem" so I tried showing the built-in dots that are usually used for a mouseover effect:
chart.on('pretransition', chart => {
const all = chart.group().all();
isolated = all.reduce((p, kv, i) => {
return (kv.value.average !== null &&
(i==0 || all[i-1].value.average == null) &&
((i==all.length-1 || all[i+1].value.average == null))) ?
{...p, [kv.key]: true} : p;
}, {});
chart.g().selectAll('circle.dot')
.filter(d => isolated[d.data.key])
.style('fill-opacity', 0.75)
.on('mousemove mouseout', null)
})
This works but it currently relies on disabling the interactivity of those dots so they don't disappear.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4