2016-02-05 3 views
1

Я работаю над проблемой, когда хочу отображать данные в приборной панели как в виде диаграммы (через perak:c3), так и в таблице (через aslagle:reactive-table). Моя проблема заключается в том, что данные извлекаются из коллекции в MongoDB, и ее формат мгновенно поддается описанию через c3, но его необходимо преобразовать в локальную коллекцию, которая будет использоваться пакетом реактивной таблицы, как предложено в this answer прежний вопрос.Реакция уровня шаблона в Meteor

Когда я меняю отображаемый набор данных, я хочу обновить график, а также таблицу. Это требует изменения значений в локальной коллекции, однако это замедляет работу, и вместо того, чтобы график плавно перерисовывался, на странице происходит замораживание, а затем отображаются новые данные.

Я создал образец проекта on GitHub here, так что проблема может быть легко реплицирована. Если запустить приложение и выбрать набор данных в вашем браузере, вы увидите именно то, что я имею в виду

enter image description here

Чтобы увидеть реактивное поведение я хочу сохранить в таблице перейти к client/templates/dashboard/dashboard.html и просто закомментируйте шаблон таблицы {{> dashboardTable}}

enter image description here

и теперь изменить набор данных, чтобы увидеть, как график плавно перерисованы. По сути, я стараюсь, чтобы оба шаблона dashboardChart и dashboardTable отображались независимо друг от друга.


UPDATE

После предложение Майкла Флойда использования тайм-аут помог немного

Meteor.setTimeout(function(){createLocalCollection(data)},200); 

но хотя диаграмма становится плавно обращается, когда таблица заканчивает быть заполнены, диаграмма еще раз. Похоже, что он перескакивает в какое-то промежуточное состояние, которое я не могу понять. Here is a video показывая, что я имею в виду.

+0

Этот комментарий HTML на самом деле не мешает шаблону рендеринга - вместо этого используйте комментарий blaze: '{{! - comment -}}'. –

ответ

1

Я добавляю это как отдельный ответ, потому что это совершенно другой подход.

Используйте обратный вызов onRendered в d3 для вызова обновления локальной коллекции.

Где у вас есть:

chart = c3.generate({ 
    bindto: '#dataset-chart', 

в dashboard_chart.js, добавьте:

chart = c3.generate({ 
    onrendered: createLocalCollection(), 
    bindto: '#dataset-chart', 

Конечно, вы должны удалить createLocalCollection(data) из обработчика событий.

Чтобы избежать необходимости передавать контекст данных через onrendered обработчика в d3 также обновить createLocalCollection функцию использовать реактивную переменную datasetID, который вы определили ранее, чтобы установить текущий набор данных:

var createLocalCollection = function() { 
    var values = My_First_Collection.find({datasetID: datasetID.get()}).fetch(); 
    var tempDoc = {}; 
    local.remove({}); 
    tempDoc = {}; 
    for (var i in values[0].value) { 
     tempDoc.value = values[0].value[i]; 
     tempDoc.date = values[0].date[i]; 
     local.insert(tempDoc); 
    } 
}; 

Используя этот метод, пусть D3 скажет вам, когда выполняется рендеринг графика, а затем ваша таблица может начать заполняться. Результатом является мгновенное обновление диаграммы с последующим обновлением таблицы. Никаких выпадений с тайм-аутами.

+0

Кстати, вы, возможно, захотите переосмыслите свой подход к локальной коллекции. Самый дорогой аспект - это «local.insert()». Для этого вы могли индексировать эту коллекцию с помощью 'datasetID', так что вам не нужно каждый раз перестраивать ее, во-вторых, вы можете кэшировать другие диаграммы, пока пользователь смотрит на данный момент –

+0

Это отлично работает. Я также гарантировал, что 'datasetID 'индексируется, включая' My_First_Collection._ensureIndex ({"datasetID": 1}) 'в блоке' Meteor.startup() '. За столом все еще есть задержка, но сейчас я могу жить с ней. Благодарим вас за помощь и понимание. –

1

Помните, что js однопоточный. У вас есть две вещи, и они будут происходить последовательно. Что вы можете сделать, это defer код, который обновляет локальную коллекцию, используя Meteor.setTimeout(). Это позволит сначала обновить диаграмму, а затем вторая таблица может обновиться. Я видел это раньше, когда вы запускаете функцию, которая обновляет DOM (в вашем случае d3 обновляет холст svg), но фактическое обновление экрана застревает за длинными js.

Я пробовал это специально, и графика была в порядке.

Meteor.setTimeout(function(){createLocalCollection(data)},500); 

Режущий интервал до 100 позволил график обновления, но затем в меню не исчезнет полностью, пока местный сбор не закончил обновление.

Одна вещь, которую я использовал с таблицами и локальными коллекциями, заключается только в обновлении локального документа коллекции, когда соответствующий нелокальный документ отображается на экране (при условии, что между исходными данными и преобразованная версия). Это позволяет лениво загружать реактивную таблицу.

+0

Так что вместо 'updatePlot (data); createLocalCollection (данные); 'Я пытаюсь' updatePlot (data); Meteor.setTimeout (createLocalCollection (data), 5000); ', но это не имеет никакого эффекта, независимо от используемой длины таймаута –

+0

Мне нужно будет вставить код в свой код, чтобы узнать, что я могу найти. –

+0

'setTimeout' принимает функцию в качестве первого параметра. Вам просто нужно было анонимизировать ваш вызов 'createLocalCollection' –

Смежные вопросы