Обновление в режиме реального времени графикам Д3 разъемом.Ио


Я пишу d3.основанная на js директива диаграммы реального времени. Структура выглядит следующим образом:

Мое направление.js :

app.directive('myDirective', function(socketio) {

  return {
    restrict: 'EA',
    templateUrl: '../../views/partials/chart.html',
    controller: DataController,

    link: function(scope, elem, attrs, ctrl) {

      scope.Watch = scope.$watch(function() {
        return ctrl.data;
      }, function(newVal) {
        // d3 code part
      });

      socketio.on(event, function(newdata) {
        ctrl.data.push(newdata);
        // redraw chart
      });
    }
  };
});

В приведенной выше части кода d3 я ссылаюсь на http://bl.ocks.org/gniemetz/4618602. основной код почти такой же, и диаграмма отображается хорошо.

Теперь я хочу использовать socket.io чтобы обновить диаграмму с помощью кода

socketio.on(event, function(newdata) {
  ctrl.data.push(newdata);
  // redraw chart
});

Но не знаю, как эффективно перерисовать диаграмму с помощью обновленного ctrl.данные'. Я знаю в Моррис.Джей-Эс, мы могли бы сделать это с помощью '.метод setdata(упр.data) ' метод, но не знаю, как обновить в d3. Есть идеи?

Ps: Я пытался скопировать / вставить код d3 выше в это место, но всегда была ошибка: "TypeError: t. slice-это не функция"

Спасибо,

1 2

1 ответ:

Быстрый и грязный способ: каждый раз, когда у вас есть обновление, очистите <div> и перерисуйте весь график.

Более элегантный способ: напишите свою собственную функцию update для добавления новых данных. Это, безусловно, наиболее визуально привлекательный способ, так как график на самом деле будет анимирован. D3 хорошо построен для такого рода вещей, так что его ни в коем случае не растягивать свои возможности. Это займет немного больше времени, но обычно обеспечивает гораздо более приятный опыт, Как видно на некоторые графики в галерее D3 (примеры: http://square.github.io/crossfilter/ , http://bl.ocks.org/NPashaP/96447623ef4d342ee09b ) Вот как бы я это сделал, используя нужный вам график:

  • сохраняйте ваш код таким же
  • добавьте функцию обновления, скажем, с именем Update(), которая вызывается в разделе socketio.on(...), где вы прокомментировали // redraw chart
  • Update() затем переопределит все переменные D3 и оживит изменение

Update() будет по существу делать то выше пуля, выполнив подмножество шагов, используемых при создании графика с нуля. Вот обзор того, что он будет делать: масштабировать обе оси x и y, графически обновлять оси, переводить исходные точки и линии в их новые позиции на новых осях, добавлять новые точки и добавлять любые линии, которые могут потребоваться для завершения графика

Я работаю над jsFiddle для вас с рабочим Update, чтобы продемонстрировать вышесказанное и, надеюсь, реализовать его в вашем коде будет просто. Я это отредактирую сообщение, когда его сделали, но я хотел дать вам "быстрый" ответ, пока я работаю над ним в попытке помочь вам тем временем. Если вы хотите немного почитать, проверьте http://blog.visual.ly/creating-animations-and-transitions-with-d3-js/


Обновить

Https://jsfiddle.net/npzjLng9/2/. я взял приведенный вами пример и должен был изменить загружаемые данные, чтобы они были локальными, а не из текстового файла; однако они находятся в том же формате, и также намного меньше записей для удобства чтения. Кроме этого, я не внес никаких изменений в пример. Вот что я добавил: прокрутите вниз и найдите последнюю функцию, Update. Вот где происходит обновление и анимация. Обратите внимание на поток функции:

  1. "обновите" данные, как если бы ваш socket.io был тем, кто получил их, а затем добавил к набору данных.
  2. переопределить оси
  3. переопределите точки и пути
  4. укажите длительность перехода (feel свободно играть с любым номером, который вам подходит)
  5. фактически обновить и оживить изменения на сюжете

Я добавил кнопку для имитации события приема socket.io.

Для вашего приложения игнорируйте data.push и console.log в функции Update(), и я думаю, что это все, что вам нужно-кроме указания данных на Ваш массив ctrl.data и запуска функции Update() в вашем socketio.on(...), Конечно.

Та же основная схема применяется к анимации / обновлению большинства диаграммы.

Я надеюсь, что это поможет вам!