dc.js lineChart - показать ноль, где нет данных - PullRequest
0 голосов
/ 11 мая 2018

У меня есть lineChart dc.js, который показывает количество событий в час. Я хотел бы вместо того, чтобы соединять строку между двумя известными значениями, значение должно быть показано как ноль.

Так что для данных ниже я бы хотел, чтобы линия опустилась до нуля в течение 10 часов утра.

{datetime: "2018-05-01 09:10:00", event: 1}
{datetime: "2018-05-01 11:30:00", event: 1}
{datetime: "2018-05-01 11:45:00", event: 1}
{datetime: "2018-05-01 12:15:00", event: 1}

var eventsByDay = facts.dimension(function(d) { return d3.time.hour(d.datetime);});
var eventsByDayGroup = eventsByDay.group().reduceCount(function(d) { return d.datetime; });  

Я посмотрел на определенное, но не думаю, что это правильно, я думаю, что мне нужно добавить нулевое значение в данные для каждого часа, который не имеет данных? Однако я не уверен, как это сделать, и я не могу найти пример того, что я пытаюсь в dc.js

Этот другой вопрос отвечает на этот вопрос, но для d3.js, и я не уверен, как перевести это - Линейная диаграмма d3 - Показать 0 на оси Y, не проходя во всех точках?

Кто-нибудь может указать мне правильное направление?

Спасибо!

1 Ответ

0 голосов
/ 14 мая 2018

Вы на правильном пути с ensure_group_bins, но вместо того, чтобы заранее знать требуемый набор корзин, в этом случае нам нужно их вычислить.

К счастью, d3 предоставляет interval.range , который возвращает массив дат для каждой границы интервала между двумя датами.

Затем нам нужно объединить-отсортировать этот набор с ячейками из исходной группы. Возможно, я немного переработал это, но вот функция для этого:

function fill_intervals(group, interval) {
  return {
    all: function() {
      var orig = group.all().map(kv => ({key: new Date(kv.key), value: kv.value}));
      var target = interval.range(orig[0].key, orig[orig.length-1].key);
      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.valueOf() === target[ti].valueOf())
            ++ti;
        } else {
          result.push({key: target[ti], value: 0});
          ++ti;
        }
      }
      if(oi<orig.length)
        Array.prototype.push.apply(result, orig.slice(oi));
      if(ti<target.length)
        Array.prototype.push.apply(result, target.slice(ti).map(t => ({key: t, value: 0})));
      return result;
    }
  }
}

По сути, мы выполняем итерации как для исходных, так и для целевых корзин и выбираем, что меньше. Если они одинаковы, то мы увеличиваем оба счетчика; в противном случае мы просто увеличиваем нижний.

Наконец, когда один из массивов исчерпан, мы добавляем все остальные результаты из другого массива.

Вот пример скрипты, основанной на вашем коде.

Он написан на D3v4, но вам нужно только изменить d3.timeHour в двух местах на d3.time.hour, чтобы использовать его с D3v3.

Я добавлю эту функцию в FAQ!

...