Я пытаюсь создать диаграмму с разбивкой по дате, используя dc.js. Эта диаграмма должна:
Это мой код:
var data = [{
"event": "Panic",
"date": "2018-01-02"
}, {
"event": "Speed limit exceeded",
"date": "2018-01-01"
}, {
"event": "Door opened",
"date": "2018-01-03"
}];
var chart = dc.lineChart("#areaChart");
var dtgFormat = d3.time.format("%Y-%m-%d");
data.forEach(function(d) {
d.dtg = dtgFormat.parse(d.date);
});
var ndx = crossfilter(data);
var areaDim = ndx.dimension(function(d) {
return d.dtg;
});
var areaGroup = areaDim.group().reduce(
function(p, v) {
p[v.event] = (p[v.event] || 0) + 1;
return p;
},
function(p, v) {
p[v.event] = (p[v.event] || 0) - 1;
return p;
},
function() {
return {};
});
// Get distinct
var eventsArray = data.map(a => a.event).filter(function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
});
function sel_stack(i) {
return function(d) {
return d.value[i];
};
}
chart.width(960)
.height(150)
.transitionDuration(500)
.dimension(areaDim)
.group(areaGroup, eventsArray[0], sel_stack(eventsArray[0]))
.renderArea(true)
.elasticY(true)
.x(d3.time.scale().domain(d3.extent(data, function(d) {
return d.dtg;
})))
.xAxis().ticks(4);
for (var i = 1; i < eventsArray.length; i++)
chart.stack(areaGroup, eventsArray[i], sel_stack(eventsArray[i]));
dc.renderAll();
Но диаграмма только рисует обе оси. Что мне не хватает?
Вот мой jsfiddle: http://jsfiddle.net/n08e32n6/12/
Функция стека dc.js требует, чтобы каждый стек имел значение для каждого значения X. Поскольку некоторые из них в настоящее время undefined
вы получаете NaN
а затем dc.js полностью дезактивирует области.
Все, что вам нужно сделать, это инициализировать объекты сокращения со всеми доступными ключами вместо запуска с пустым объектом. Таким образом, вы можете сначала вычислить свои отдельные типы событий, а затем использовать Array.reduce
для создания объекта с нулями для каждого типа события:
var eventsArray = data.map(a => a.event).filter(function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
});
var areaGroup = areaDim.group().reduce(
function(p, v) {
p[v.event] = (p[v.event] || 0) + 1;
return p;
},
function(p, v) {
p[v.event] = (p[v.event] || 0) - 1;
return p;
},
function() {
return eventsArray.reduce(function(p, v) {
p[v] = 0;
return p;
}, {});
});